将ID数组转换为地图对象

时间:2017-12-06 21:42:55

标签: javascript arrays lodash

我正在寻找一种简洁的方法来创建一个对象,其属性名称与数组中的值匹配,其中所有属性具有相同的值(例如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>

3 个答案:

答案 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)

的ID

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>