假设您有一个非常简单的数据结构:
(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'}
};
第二个或第三个选项显然是如果您有(或期望您可能有)多个“价值”部分要存储(例如,添加他们的年龄或某事)的方式,所以,为了这个缘故参数,让我们假设在这个结构中永远不会再有任何数据值。你选择哪一个?为什么?
修改:该示例现在显示最常见的情况:非顺序ID。
答案 0 :(得分:57)
每个解决方案都有其用例。
我认为如果您尝试定义一对一关系(例如简单映射),第一个解决方案是好的,特别是如果您需要将密钥用作查找键。
第二种解决方案对我来说感觉最强大,如果我不需要快速查找键,我可能会使用它:
如果您需要快速查找时间+上面列出的一些优点(传递数据,自我描述),第三个会很好。但是,如果您不需要快速查找时间,则会更加繁琐。此外,无论哪种方式,如果对象中的ID与人中的ID有所不同,则会冒错误的风险。
答案 1 :(得分:7)
实际上,还有第四种选择:
var people = ['Joe', 'Sam', 'Eve'];
因为您的值恰好是连续的。 (当然,你必须添加/减去一个---或者只是将undefined作为第一个元素)。
就个人而言,我会选择你的(1)或(3),因为那些通过ID(O log n )查找最快的人是最快的。如果你必须在(2)中找到id 3,你可以通过索引查找(在这种情况下我的(4)没问题)或你必须搜索 - O(n)。
澄清:我说O(log n )是最糟糕的,因为AFAIK和实现可能决定使用平衡树而不是哈希表。假设冲突最小,哈希表将为O(1)。
从nickf编辑:我已经改变了OP中的示例,所以这个答案可能不再那么有意义了。道歉。
好的,编辑后,我会选择选项(3)。它是可扩展的(易于添加新属性),具有快速查找功能,并且可以进行迭代。如果需要,它还允许您从登记返回到身份证。
如果(a)你需要节省内存,选项(1)将是有用的; (b)你永远不需要从物体回到身份; (c)您永远不会扩展存储的数据(例如,您不能添加该人的姓氏)
如果您(a)需要保留排序,则选项(2)是好的; (b)需要迭代所有元素; (c)不需要按id查找元素,除非它按id排序(你可以在O(log n )中进行二进制搜索。注意,当然,如果你需要保留它排序然后你将支付插入成本。
答案 2 :(得分:2)
假设数据永远不会改变,第一个(单个对象)选项是最好的。
结构的简单性意味着它是最快的解析,并且在小的,很少(或从不)改变这样的数据集的情况下,我只能想象它会经常被执行 - 在这种情况下最小化开销是要走的路。
答案 3 :(得分:2)
我创建了一个小型库来管理键值对。
https://github.com/scaraveos/keyval.js#readme
使用
希望有所帮助:)
答案 4 :(得分:1)
第三个选项对于任何前瞻性应用程序都是最佳选择。您可能希望在人员记录中添加更多字段,因此第一个选项不合适。此外,您很可能会有大量人员要存储,并希望快速查找记录 - 因此将它们转储到一个简单的数组中(如选项#2中所做的那样)也不是一个好主意。
第三种模式允许您选择使用任何字符串作为ID,具有复杂的Person结构并在恒定时间内获取和设置人员记录。这绝对是要走的路。
选项#3缺少的一个问题是稳定的确定性排序(这是选项#2的好处)。如果您需要这个,我建议您将有序的人员ID数组作为单独的结构保存,以便在需要按顺序列出人员时。优点是你可以保留多个这样的数组,用于同一数据集的不同排序。
答案 5 :(得分:0)
鉴于您的约束条件,您只会将名称作为值,我会选择第一个选项。它是最干净的,具有最少的开销和最快的查找。