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

nic*_*ckf 80 javascript data-structures

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

(personId, name)
Run Code Online (Sandbox Code Playgroud)

...并且您希望将其中的一些存储在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'}
};
Run Code Online (Sandbox Code Playgroud)

第二个或第三个选项显然是如果你有(或期望你可能有)不止一个"价值"部分来存储(例如,添加他们的年龄或某事)的方式,所以,为了争论,让我们假设这个结构中永远不会再需要任何数据值.你选择哪一个?为什么?


编辑:现在示例显示最常见的情况:非顺序ID.

Dan*_*Lew 58

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

我认为如果您尝试定义一对一关系(例如简单映射),第一个解决方案是好的,特别是如果您需要将密钥用作查找键.

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

  • 它是自我描述的,因此您不必依赖任何使用 人的人知道密钥是用户的ID.
  • 每个对象都是自包含的,这对于将数据传递到其他地方更好 - 而不是只传递给人们的两个参数(id和name).
  • 这是一个罕见的问题,但有时键值可能无法用作键.例如,我曾经想要映射字符串转换(例如,":"到">"),但由于":"不是有效的变量名称,我必须使用第二种方法.
  • 它很容易扩展,如果需要向某些(或所有)用户添加更多数据.(对不起,我知道你的"为了论证而已",但这是一个重要的方面.)

如果您需要快速查找时间+上面列出的一些优点(传递数据,自我描述),第三个将是好的.但是,如果您不需要快速查找时间,则会更加繁琐.此外,无论哪种方式,你运行出错的风险,如果在对象的ID以某种方式从ID不同的人.

  • @derobert:我不这么认为.x = {"delete":1,"for":2,"function":3}; - 这是有效的,可以以相同的方式访问. (4认同)

der*_*ert 7

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

var people = ['Joe', 'Sam', 'Eve'];
Run Code Online (Sandbox Code Playgroud)

因为你的价值恰好是连续的.(当然,你必须添加/减去一个---或者只是将undefined作为第一个元素).

就个人而言,我会选择你的(1)或(3),因为那些通过ID查找某人是最快的(最糟糕的是O log n).如果你必须在(2)中找到id 3,你可以通过索引查找它(在这种情况下我的(4)没问题)或你必须搜索 - O(n).

澄清:我说O(log n)是最糟糕的,因为AFAIK和实现可能决定使用平衡树而不是哈希表.假设冲突最小,哈希表将为O(1).

从nickf编辑:我已经改变了OP的例子,所以这个答案可能不再那么有意义了.道歉.

后期编辑

好的,编辑后,我会选择选项(3).它是可扩展的(易于添加新属性),具有快速查找功能,并且可以进行迭代.如果需要,它还允许您从入口返回到ID.

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

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