【问题标题】:Using an array as a hash table使用数组作为哈希表
【发布时间】:2014-12-04 13:24:52
【问题描述】:

这基本上是一个 javascript 中的编程风格问题。

有时当我编码时,我发现自己在循环浏览一组数据,例如,一组用户:

var users = [
    {
        id: 'USER-435',
        name: 'James',
        email: 'james@gmail.com'
    },{
        id: 'USER-7897',
        name: 'Mark',
        email: 'mark@gmail.com'
    },{
        id: 'USER-2345',
        name: 'Harry',
        email: 'harry@gmail.com'
    }
] 

重要提示:此数据来自服务器,需要按顺序排列。

如果我想通过 ID 获取特定用户的属性,我将不得不遍历数组来找到它。

所以我所做的就是遍历数组一次,并在数组中创建属性,以用户 ID 作为其键。这样我就可以使用每个用户的 ID 访问每个用户,而无需遍历数组。因为 = 运算符创建的是对对象的引用而不是副本,所以添加到数组中的每个属性都是引用。

我发现的唯一问题是,如果用户的 ID 是数字,它将成为数组的一部分。因此,如果我们有一个包含 3 个用户的集合,其中一个用户的 ID 是 120,那么会将数组的长度设置为 121。可以快速将属性添加为“id-120”,但感觉不到很干净。

我还可以为集合创建一个单独的对象,而不是在数组中创建新属性,但这会创建一个我需要处理的新对象。

我只是想问问人们对这种模式的看法,以及你是否有更好的方法。

【问题讨论】:

    标签: javascript arrays hashmap coding-style hashset


    【解决方案1】:

    您只有几个选项可以完成此操作。将数组重新映射到对象以通过键进行查找是一种非常常见的模式。

    我不会太担心创建 'users_by_id' 对象,它不太可能给您带来太多麻烦(除非您的代码已经非常复杂)

    但是,对于您的特定问题,我有一个建议。为什么不在数组上创建一个名为“by_id”的属性,并使其成为您按 id 索引的对象。

    users.by_id['USER-2345'];
    

    它解决了“额外变量”问题、击键问题,并且代码在启动时变得一目了然。

    祝你好运。

    PS - 也可以查看 underscore.js 或 lodash - 他们有让这种事情变得非常容易的例程。它们会为您节省大量时间。

    【讨论】:

      【解决方案2】:

      我会在这里使用Array.filter。比如:

      users.filter( function (v) { return v.id === 'USER-435'; } );
      

      在函数中:

      function findUser(id) {
        var user = users.filter( function (v) { return v.id === id; } );
        return user.length ? user[0] : {id: 'not found'};
      }
      

      这将需要循环,但在您的数组包含超过一百万个元素之前,我不会担心这一点。引用托尼·霍尔的话:

      我们应该忘记小的效率,比如大约 97% 的时间: 过早优化是万恶之源。

      另见MDN
      而且(公平地说)还有FALLACY OF PREMATURE OPTIMIZATION

      【讨论】:

      • 主要问题是如何避免循环遍历数组
      • 抱歉,@JayKuri 的回答更简洁
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      相关资源
      最近更新 更多