繁体   English   中英

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

[英]Objects vs arrays in Javascript for key/value pairs

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

(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。

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

我认为如果要定义一对一的关系(例如简单的映射),第一种解决方案是好的,尤其是当您需要使用该键作为查找键时。

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

  • 它是自描述的,因此您不必依赖任何使用人员的人来知道密钥是用户的ID。
  • 每个对象都是独立的,这更适合将数据传递到其他地方-而不是您随便传递两个参数(id和name)。
  • 这是一个罕见的问题,但有时键值可能无效,无法用作键。 例如,我曾经想映射字符串转换(例如,“:”到“>”),但是由于“:”不是有效的变量名,因此我不得不使用第二种方法。
  • 它很容易扩展,以防万一您需要向某些(或全部)用户添加更多数据。 (对不起,我知道您的“为争辩而已”,但这是一个重要方面。)

如果您需要快速的查找时间+上面列出的一些优点(传递数据,自我描述),那么第三种方法将是不错的选择。 但是,如果您不需要快速的查找时间,则麻烦得多。 同样,无论哪种方式,如果对象中的id与people中的id有所不同,都将有出错的风险。

实际上,有第四个选择:

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

因为您的值碰巧是连续的。 (当然,您必须添加/减去一个---或仅将undefined作为第一个元素)。

at worst). 就我个人而言,我会选择您的(1)或(3),因为这些将是通过ID查找某人的最快方法(最糟糕的情况是O log )。 如果必须在(2)中找到id 3,则可以按索引查找它(在这种情况下,我的(4)可以),或者必须搜索— O(n)。

) is the worst it could be because, AFAIK, and implementation could decide to use a balanced tree instead of a hash table. 澄清:我说O(log )是最糟糕的,因为AFAIK和实现可以决定使用平衡树而不是哈希表。 假设冲突最少,则哈希表为O(1)。

从nickf编辑:从那以后,我在OP中更改了示例,因此此答案可能不再那么有意义。 道歉。

编辑后

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

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

如果您(a)需要保留排序,则选项(2)很好。 (b)需要迭代所有元素; ). Note, of course, if you need to keep it sorted then you'll pay a cost on insert. (c)不需要按id查找元素,除非按id对其进行排序(您可以在O(log )中进行二进制搜索。当然,请注意,如果需要对其进行排序,则需要付费插入成本。

假设数据永远不会改变,则第一个(单个对象)选项是最佳选择。

结构的简单性意味着它是最快的解析方法,对于像这样的小型,很少(或永远不会)更改的数据集,我只能想象它会被频繁执行-在这种情况下,最小的开销是要走的路。

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

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

它用

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

希望能帮助到你 :)

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

第三种模式使您可以选择使用任何字符串作为ID,具有复杂的Person结构并在固定时间内获取和设置Person记录。 这绝对是要走的路。

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

鉴于您的限制,即您将只能使用名称作为值,因此我选择第一个选项。 它是最干净的,开销最小且查找最快的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM