对象与 Javascript 中键/值对的数组

假设你有一个非常简单的数据结构:

(personId, name)

你想要在 javascript 变量中存储一些这样的东西。在我看来,你有三个选择:

// a single object
var people = {
1 : 'Joe',
3 : 'Sam',
8 : 'Eve'
};


// or, an array of objects
var people = [
{ id: 1, name: 'Joe'},
{ id: 3, name: 'Sam'},
{ id: 8, name: 'Eve'}
];


// or, a combination of the two
var people = {
1 : { id: 1, name: 'Joe'},
3 : { id: 3, name: 'Sam'},
8 : { id: 8, name: 'Eve'}
};

第二个或第三个选项显然是如果你有(或者期望你可能有)多个“值”部分要存储(例如,添加他们的年龄或其他东西) ,那么,为了讨论,让我们假设这个结构永远不会需要更多的数据值。你选择哪一个? 为什么?


Edit : 该示例现在显示了最常见的情况: 非顺序 id。

71375 次浏览

实际上,还有第四种选择:

var people = ['Joe', 'Sam', 'Eve'];

因为你们的价值观是连续的。(当然,您必须添加/减去一个元素-- 或者只是将未定义的元素放在第一个元素中)。

就我个人而言,我会选择你的(1)或(3) ,因为这些将是最快的查找某人的 ID (O logN在最坏的情况下)。如果您必须在(2)中查找 id 3,那么您可以通过索引(在这种情况下 my (4)是 ok)查找它,或者必须搜索ー O (n)。

澄清: 我认为 O (logN)是最糟糕的,因为 AFAIK 和实现可能决定使用平衡树而不是哈希表。假设冲突最小,哈希表应该是 O (1)。

从 nickf 编辑: 我已经在 OP 中更改了示例,所以这个答案可能不再那么有意义了。抱歉。

后期编辑

好吧,后期编辑,我会选择选项(3)。它是可扩展的(很容易添加新属性) ,具有快速查找功能,并且还可以迭代。它还允许您从输入返回 ID,如果您需要的话。

选项(1)将是有用的,如果(a)你需要节省内存; (b)你永远不需要从对象返回到 id; (c)你永远不会扩展存储的数据(例如,你不能添加人的姓氏)

选项(2)是好的,如果你(a)需要保持排序; (b)需要迭代所有元素; (c)不需要通过 id 查找元素,除非它是按 id 排序的(你可以在 O 中进行二进制搜索(logN)。注意,当然,如果您需要保持它的排序,那么您将为插入支付一定的成本。

每个解决方案都有其用例。

我认为,如果您试图定义一对一关系(比如简单映射) ,第一种解决方案是很好的,特别是如果您需要使用键作为查找键。

总的来说,第二种解决方案感觉最健壮,如果不需要快速查找键,我可能会使用它:

  • 这是自我描述,所以你不会 不得不依靠任何使用 人们知道密钥是用户的 id。
  • 每个物体都是独立的, 更适合传递数据 而不是两个参数 (id 和 name)你只需要传递 人。
  • 这是一个罕见的问题,但有时 键值可能无效 用作键。例如,我曾经 想要映射字符串转换 (例如,“ :”至“ >”) ,但自“ :” 不是一个有效的变量名 使用第二种方法。
  • 它很容易扩展,以防万一 在这条路上的某个地方你需要 向部分(或全部)用户添加更多数据。 (对不起,我知道你的 但这是一个 重要方面)

如果您需要快速查找时间 + 上面列出的一些优势(传递数据,自我描述) ,第三种方法会很好。但是,如果您不需要快速查找时间,那么它会非常麻烦。而且,无论哪种方式,如果对象中的 id 与 中的 id 有所不同,都会有出错的风险。

假设数据永远不会更改,那么第一个(单个对象)选项是最好的。

结构的简单性意味着它的解析速度最快,对于小型的、很少(或从不)更改数据集的情况,比如这个,我只能想象它将被频繁地执行——在这种情况下,最小的开销才是解析的方法。

考虑到您的限制,您将永远只有名称作为值,我将选择第一个选项。这是最干净的,有最少的开销和最快的抬头。

第三种选择对于任何前瞻性的应用程序都是最好的。您可能希望向您的个人记录添加更多字段,因此第一个选项不适合。另外,很有可能需要存储大量的用户,并且希望快速查找记录——因此将它们转储到一个简单的数组中(正如在选项 # 2中所做的那样)也不是一个好主意。

第三种模式允许您选择使用任何字符串作为 ID,使用复杂的 Person 结构,并在一个常量时间内获取和设置人员记录。这绝对是个好办法。

选项 # 3缺少的一件事是稳定的确定性排序(这是选项 # 2的优点)。如果需要这样做,我建议在需要按顺序列出人员时,将人员 ID 的有序数组作为一个单独的结构。这样做的好处是,您可以为同一数据集的不同排序保留多个这样的数组。

我创建了一个小库来管理键值对。

Https://github.com/scaraveos/keyval.js#readme

它使用

  • 存储密钥的对象,允许快速删除和值检索 行动及
  • 一个链表,以允许真正快速的值迭代

希望对你有所帮助:)