我正在寻找一种简洁的方法来创建一个对象,其属性名称与数组中的值匹配,其中所有属性具有相同的值(例如true
)。举个例子:
我的ID数组看起来像是任意的(在实际的软件中,不一定是唯一的,不一定是数字的,但是原始的)值:
var ids = [4, 15, 8, 16, 42, 23];
我正在寻找一些简单的调用来将其转换为以下对象:
{ 4: true, 15: true, 8: true, 16: true, 42: true, 23: true }
JavaScript对象内部是hashmaps,这样的对象应该更方便快速检查数组中是否包含给定的ID。
现在,当然我知道如何生成这个对象。这是一个四线:
var idMap = {};
ids.forEach(function (v) {
idMap[v] = true;
});
由于此模式在我的代码中反复出现(在此应用程序中处理了许多不同的项目ID),我觉得“样板”的百分比仍然太大。此外,在我看来,四线程偶尔会分散用于使用各种ID列表做某事的实际棘手的算法。因此,我正在寻找一种更简短的方法来编写它,希望对标准JavaScript或lodash有一些内置,这已经在我们的应用程序中使用了。
我能找到的最相关的问题似乎是lodash: mapping array to object。然而,它提出的解决方案并不比上面更简洁,更清晰,基本上用另一种替换一种样板代码(在我的情况下,我通常会抛弃建议的解决方案用作对象属性的值和总是使用true
或类似的小truthy值。)
是否有内置的东西允许一个非常简单的命令,如
var idMap = arrayToMap(ids);
或
var idMap = arrayToMap(ids, true);
我的实际名字还没有找到?
(显然,后备解决方案是在我们的应用程序中简单地编写这样一个函数。我宁愿尽可能地与现有函数保持一致,因此这个问题。)< / p>
答案 0 :(得分:1)
您可以创建一个为您生成地图的简单函数:
var ids = [4, 15, 8, 16, 42, 23];
function hash(arr, prop) {
return arr.reduce(function(r, n) {
r[prop ? n[prop] : n] = true;
return r;
}, {});
}
console.log(hash(ids));
var objs = [{ a: 1 }, { a: 2 }, { a: 3}];
console.log(hash(objs, 'a'));
您可以使用ES6 Set:
const ids = [4, 15, 8, 16, 42, 23];
const set = new Set(ids);
console.log(set.has(16));
答案 1 :(得分:1)
您可以将其添加到应用中的Array.prototype
:
var ids = [4, 15, 8, 16, 42, 23];
Array.prototype.toThing = function(propVal) {
return this.reduce((res, val) => {
res[val] = propVal;
return res;
}, {})
}
console.log(ids.toThing(true));
答案 2 :(得分:1)
好吧,我认为您可以轻松地将源数组映射到对数组,然后轻松构造对象(甚至是ES6 Map
)。
只是做:
_.fromPairs(ids.map(a=>[a,true]))
就是这样。
以下是一个工作示例:
var ids = [4, 15, 8, 16, 42, 23];
var idsMap = _.fromPairs(ids.map(a=>[a,true])); // however true can be replaced with a variable
console.log(idsMap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
另一种方式:
_(ids).keyBy(v=>v).mapValues(v=>true).value()
以下是工作示例:
var ids = [4, 15, 8, 16, 42, 23];
var idsMap = _(ids).keyBy(v=>v).mapValues(x=>true).value();
console.log(idsMap)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
并且,如果你确定(考虑)你的所有id都是真正的价值,那么你可以把它作为一个优势,只需创建一个具有相同键/值对的地图,并检查真实性任何直接使用O(1)
Just Do:
_.keyBy(ids)
你完成了:)
当您意识到价值的真实性时,您不需要第二个解决方案中的额外.mapValues(v=>true)
。
以下是工作片段:
var ids = [4, 15, 8, 16, 42, 23];
var idsMap = _.keyBy(ids);
console.log(idsMap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>