【发布时间】:2017-12-06 21:42:54
【问题描述】:
我正在寻找一种简洁的方法来创建一个对象,该对象的属性名称与数组中的值匹配,其中所有属性都具有相同的值(例如true)。举个例子:
我的 ID 数组看起来像这些任意(在实际软件中,不一定是唯一的,也不一定是数字,而是原始的)值:
var ids = [4, 15, 8, 16, 42, 23];
我正在寻找一些简单的调用来将其转换为以下对象:
{ 4: true, 15: true, 8: true, 16: true, 42: true, 23: true }
由于 JavaScript 对象内部是哈希图,这样的对象应该更方便快速检查给定 ID 是否包含在数组中。
现在,当然我知道如何生成这个对象了。这是一个四线:
var idMap = {};
ids.forEach(function (v) {
idMap[v] = true;
});
由于这种模式在我的代码中反复出现(在此应用程序中处理了许多不同的项目 ID),我觉得其中的“样板”百分比仍然太大。此外,在我看来,四行代码有时会分散对处理各种这些 ID 列表的实际棘手算法的注意力。因此,我正在寻找一种更短的方法来编写它,希望标准 JavaScript 或 lodash 有一些内置的东西,它已经在我们的应用程序中使用。
我能找到的最相关的问题似乎是lodash: mapping array to object。然而,它提出的解决方案并没有真正比上面更短和更易读,基本上用另一种样板代码替换了一种样板代码(在我的例子中,我通常会丢弃建议的解决方案用作对象属性的值和始终使用true 或一些类似的小真实值)。
是否有内置的东西允许使用非常简单的命令,例如
var idMap = arrayToMap(ids);
或
var idMap = arrayToMap(ids, true);
我还没找到谁的真名?
(显然,后备解决方案是在我们的应用程序中简单地编写这样一个函数。不过,我更愿意尽可能地坚持现有的函数,因此这个问题。)
【问题讨论】:
-
为什么不直接使用 indexOf:
var ids = [4, 15, 8, 16, 42, 23]; console.log(ids.indexOf(16)!=-1);?然后将其删除为false或将其更改为x16 -
@mplungjan:因为
indexOfhas a time complexity of O(n)。在处理可能很容易有数千甚至一百万个元素的 ID 集时使用它是相当不明智的,并且会快速连续进行许多此类检查。相比之下,对象内部是哈希映射,访问对象属性应该是 O(1)。 -
好的。我的错。在您的问题中没有实际提及一千或一百万个元素
-
由于数组的大小,您担心 O(1) 与 O(n) 的性能,我想知道您是否考虑过使用 JavaScript 以外的其他技术来做到这一点?像数据库?
-
@James:也许,建议使用不同技术的解决方案仍然可以从 Web 应用程序的客户端部分离线使用,这也是一个有效的答案。
标签: javascript arrays lodash