【问题标题】:Javascript efficient search array for value with jQuery使用 jQuery 进行值的 Javascript 高效搜索数组
【发布时间】:2012-12-24 05:35:11
【问题描述】:

我的 JavaScript 知识在这里存在差距。我想在对象值数组中搜索特定值并返回它。

在我编写 JavaScript 的这一年里,我一直在这样实现它:

var itemClicked = (function(){

  var retval;

  //Note self.inventory.itemsArray is an array of JS objects

  $(self.inventory.itemsArray).each(function(i){
    if(parseInt(this.id) === parseInt(idOfItem)){
      retval = this;
      return false;
    }
  });

  return retval;

})();

它有效,但我敢肯定还有更优雅的方式。请告诉我!

编辑 - 解决方案

感谢@gdoron 的回答。

var myVar = $(self.owner.itemsArray).filter(function(){
   return parseInt(this.id) == parseInt(recItemID);
}).get(0);

注意:.get(0) 添加在末尾,因为 myVar 被包装为 jQuery 对象。

【问题讨论】:

  • 定义“更高效。”有些人会误解“less characters
  • 那么self.inventory.itemsArray是一个选择器数组还是jQuery对象?
  • 为什么不按 id 索引你的数组?他们只需要做return self.inventory.itemsArray[id] 并完全避免循环。
  • 高效是什么意思?如果您正在寻找性能,您可能希望按 id 对数组进行排序并执行二进制搜索以实现 O(n log n) 时间复杂度 - 甚至通过按 @987654329 存储项目来切换到 O(n) 的哈希映射@。如果您只想编写更少的代码,请使用$.filter()
  • 这是一个 Javascript 对象数组。效率更高,字符更少,并且在找到之前不必在循环中执行可能无用的代码

标签: javascript jquery arrays search object


【解决方案1】:

用于此的原生 jQuery 函数是 filter:

$(data).filter(function(){
    return this.id == "foo";
});

它比您拥有的代码更短,更重要的是更具可读性。
关于效率,它会迭代集合中的所有元素以找到尽可能多的匹配项,但我几乎不相信它会成为您应用程序的瓶颈,不要专注于微优化

我建议你阅读关于Which is faster 的 Eric Lipper 博客。

您也可以按照@Mattias Buelens 的建议使用grep

$.grep(data, function(ele){
    retun ele.id == "foo";
});

【讨论】:

  • 原生于 jq,而不是原生于该语言。您可能希望对此更准确。
  • @gustafr,我相信这很明显,但我会添加它。
  • 这个解决方案不必要地将数组包装在一个 jQuery 对象中。 $.find 在传递函数时映射到 jQuery.grep,因此最好直接使用 grep,如 @Bruno 所示。
  • 在末尾粘贴 .get(0) 可以解决问题。这是我想要的解决方案。谢谢。
【解决方案2】:

使用 jQuery 的 $.grep( ) 函数的另一种选择

var arr = $.grep( self.inventory.itemsArray, function ( n ) { 
    return n.id == idOfItem;
});

上面返回一个匹配数组元素的数组。如果您只想要第一个,则很容易返回 arr[0](如果存在)。

【讨论】:

  • grep 不返回一个数组,而不是第一个匹配的对象吗?
  • $.filter 不同,jQuery.grep 不需要将数组包装在 jQuery 对象中。不过,这两种解决方案仍然可以找到 all 匹配元素。我似乎找不到可以在第一次匹配后停止搜索的原生 Array 方法或 jQuery 函数。
  • @MattiasBuelens, each 当返回 false 时停止迭代。虽然我仍然会使用filter,因为它更具可读性。
  • @gdoron OP 评论说他希望阻止这些额外的迭代,但你是绝对正确的,它们不会导致明显的性能下降。
  • 是的@gdoron 这就是我在原件中停止搜索的内容,谢谢。但是,是的,.filter 更具可读性。 Mattias Buelens,也感谢您的帮助。这些 ID 来自我的数据模型,所以我知道它们是独一无二的,所以这并不重要。感谢你的帮助。为 grep +1。
【解决方案3】:

虽然我不确定该函数实际上应该做什么(由于外部上下文的变量),但以下循环应该更有效

var itemClicked = (function(){

  var i, array = self.inventory.itemsArray, length = array.length;

  for( i=0; i < length; i++) {

    if(parseInt(array[i].id) === parseInt(idOfItem)){
      return array[i];
    }

  }

  return undefined;

})();

【讨论】:

    【解决方案4】:

    这是一个 Javascript 对象数组

    那么就不要使用jQuery了。至少,使用$.each 而不是围绕数组构建包装对象。不过,一个简单的 for 循环更短且性能更高:

    var itemClicked = (function(idnum) {
        var arr = self.inventory.itemsArray;
        for (var i=0, l=arr.length; i<l; i++)
            if (parseInt(arr[i].id, 10) === idnum)
                return arr[i];
    })( parseInt(idOfItem, 10) );
    

    您不妨考虑立即将 id 属性存储为数字,这样您就不需要每次都转换它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-10
      • 1970-01-01
      • 2015-12-07
      • 2020-02-01
      • 2014-01-11
      • 2018-04-23
      • 2021-06-09
      • 2014-04-30
      相关资源
      最近更新 更多