【问题标题】:What's the best way to query an array in javascript to get just the items from it I want?在javascript中查询数组以从中获取我想要的项目的最佳方法是什么?
【发布时间】:2011-03-10 09:37:33
【问题描述】:

我有一个这样的数组(只有 3000 多个对象,而不是这里的 3 个):

items = [{name:'charlie', age:'16'}, {name:'ben', age:'18'}, {name:'steve', age:'18'}]

返回仅包含 18 岁人群对象的数组的最佳方法是什么?所以我想要:

items = [{name:'ben', age:'18'}, {name:'steve', age:'18'}]

我能想到的最好的就是这个(使用 jQuery):

newArray = []
$.each(items, function(index, item) {
    if(item.age=='18') {
        newArray.push(item)
    }
})

考虑到有 3000,000 个对象,而且我一次要进行多达 50 次比较,这需要大量循环。有没有更好的办法?

【问题讨论】:

  • 为了进一步澄清,我在从数据库加载初始页面时创建了这个数组。在整个体验过程中都需要相同的信息,所以我认为从这个数组访问它可能比每次都调用回数据库更快。无论如何,我一开始就需要它,所以我猜这是有道理的。如果有更好的方法,请纠正我。
  • 肯尼:你看过@david的解决方案了吗!!?!?

标签: javascript jquery arrays


【解决方案1】:

你可以使用纯javascript

var wanted = items.filter( function(item){return (item.age==18);} );

如果您的浏览器不支持 1.6 版的 javascript,您可以在 https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter 找到过滤方法的实现


更新

Speedwise 与正常循环有一个 巨大 不同的 在测试中出现错误 差异(取决于浏览器)..看看我在http://jsperf.com/array-filter-vs-loop/3做的这个小测试

【讨论】:

  • 这看起来很简单,我喜欢它并且可以用它做更多的事情。只是围绕这些其他一些建议来看看是否有更好的性能方面,我假设这个循环在后台相当多,但也许不会成为问题。
  • @Kenny Flannery:“缺点”是您对每个项目进行函数调用。普通的for 循环可能更快。
  • 不错的测试链接,现在使用 for 循环。
【解决方案2】:

使用 find() 和 filter() 方法获取匹配项和项

如果你想要第一个匹配的单个项目,请使用返回单个对象的 find() 方法。

如果要全部匹配,请使用返回对象数组的 filter() 方法。

let items = [{name:'charlie', age:'16'}, 
{name:'ben', age:'18'}, 
{name:'steve', age:'18'}]

let all = items.filter(item=> item.age==='18')
console.log(all);

let single = items.find(item=> item.age==='18')
console.log(single);

【讨论】:

    【解决方案3】:

    如果您要经常进行搜索,最好将您的数据版本保存在可快速访问的表单中。 我使用了 underscore.js (http://documentcloud.github.com/underscore/) 来简化自己的工作,但这里的代码将创建一个对象来保存您的按年龄字段索引的数据。

    你最终会得到如下所示的东西:

    {
        "16": [
            {
                "name": "charlie",
                "age": "16"
            }
        ],
        "18": [
            {
                "name": "ben",
                "age": "18"
            },
            {
                "name": "steve",
                "age": "18"
            }
        ]
    }
    

    代码:

    var itemsByAge = _(items).reduce(function(memo, item) {
        memo[item.age] = memo[item.age] || [];
        memo[item.age].push(item);
        return memo;
    }, {});
    
    alert(JSON.stringify(itemsByAge["18"]));
    

    【讨论】:

      【解决方案4】:

      无论您选择哪种方法(items.filter 或任何 json 的“查询语言”),for 循环都是不可避免的。

      如果性能是一个问题,我建议您使用纯 JavaScript 而不是像 jQuery 这样的库,这会增加整个处理的开销,这很明显here

      因此,您的代码如下所示:

      var newArray = [];
      for(var i=0;i<items.length;i++) {
          var item = items[i];
          if(item.age == '18') {
              newArray.push(item);
          }
      });
      

      【讨论】:

        【解决方案5】:

        利用javascript宏大的函数eval()在运行时将字符串评估为代码,我们可以为Array类型定义一个原型方法

        Array.prototype.where = function (query) {
        var newArray = [];
        for(var i=0; i<this.length; i++) {
            var item = this[i];
            if(eval( "item" + query )) {
                newArray.push(item);
            }
        }
        return newArray;
        };
        

        并将它与任何数组一起使用,将查询作为字符串传递

        var newArray= items.where('.age >= 18');
        

        【讨论】:

          【解决方案6】:

          使用数组的过滤方法,它为数组中的每个元素调用一次提供的回调函数。

          array.filter(<callbackfucntion>[, <Object to use>])
          

          【讨论】:

          • 不得不提的是,这是在 ES5 中引入的方法,可能并非所有浏览器都可用(尤其是旧浏览器)。
          • 啊,学到了新东西!不知道。谢谢@Felix
          【解决方案7】:

          一旦我遇到了这样的问题,我就这样解决了 1-创建数组数组 2-每个索引创建一个索引记录 例如

          var pAry=[];
          var cAry=[{name:'ben', age:'18'}, {name:'steve', age:'18'}]
          pAry[17]=cAry;
          

          这样,当你需要 18 岁的人时,你将获得索引 17。

          【讨论】:

          • 这与我确定的很接近,除了所有一个关联数组或对象。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-13
          • 1970-01-01
          • 2021-09-23
          相关资源
          最近更新 更多