【问题标题】:Checking the existence of an object with a certain property within an array检查数组中是否存在具有特定属性的对象
【发布时间】:2012-11-12 23:26:43
【问题描述】:

请记住,我还没有足够的词汇量来知道要搜索哪些关键字(现在只是加入编码潮流......),所以这可能是一个非常容易回答的问题!

我有一个对象数组,比如说

M = [A_1, A_2, ..., A_n]

,其中 A_i 是类的实例化

A = {text: "string", coords:[x,y]}

我的问题是:检查我的数组 M 是否包含对象 A_i 的快速、优雅、简单的方法是什么

A_i.text="your mom" && A_i.coords = [9,9]

是真的吗?

我可以访问 underscore.js,它似乎有一些漂亮的做事方式,但我对如何实现它有点困惑......

我尝试过的(使用 underscore.js 库)是:

var isitso = _.find(M, function (i) { 
    return i.text == "your mom" && i.coords == [9,9];
});

在学习 JS 的这个阶段,我希望有许多不同的方法来解决这个问题。只是看看可以做什么以及如何做。

提前致谢!

【问题讨论】:

  • 具体的术语和关键字不如良好的代码格式重要。请阅读常见问题解答,了解如何使用 Markdown 正确格式化您的问题。
  • 谢谢,美化了一下。
  • 你展示的例子不起作用吗?
  • 它没有。将结果打印到控制台会出现“未定义”
  • 只是一些关于js中使用的术语的注释。 "A = {text: "string", coords:[x,y]}" 是 object literal 的实例化,而不是类。 js 中没有类(还)。沿着这些思路,如果您说 A_i 是 A 的实例化,那么 A 将是一个返回对象新实例的函数。看到这个小提琴。 jsfiddle.net/BcpVB

标签: javascript list search object


【解决方案1】:

你所拥有的困难在于数组相等是引用相等(它们必须是相同的内存位置),而不是值相等(它们具有相同的值)。如果您将支票更改为:

      return i.text == 'your mom' && i.coords[0] == 9 && i.coords[1] == 9;

它应该工作。在这种情况下,您将检查第一个 (0) 和第二个 (1) 元素是否具有必要的值,而不是比较数组对象本身。比较数字确实比较值而不是参考。

【讨论】:

  • 太棒了。有没有一种方法可以检查数组的值相等性,而无需将数组分解为其组件然后检查标量相等性?
  • @psychetician - 编写一个遍历数组的函数,检查每个值,如果它通过整个两个数组而没有发现差异,则仅返回 true。一个小的优化是在检查值之前首先检查它们的长度是否相同。您还可以在第一个差异上返回 false,中止其余的比较。
  • 您不应该使用=== 而不是==吗?
  • @ErikE - 在这种情况下,很明显第一个是字符串,坐标是整数,因此无论如何都不会进行类型转换,因为它们属于同一类型。
  • 这正是您使用=== 的原因。要允许类型转换,请使用 ==。当您不想允许类型转换时不使用=== 违反了最佳实践。你的逻辑完全倒退了。
【解决方案2】:

您无法检查数组是否相等。您需要执行以下操作:

_.find(M, function (i) { 
    return i.text == "your mom" && i.coords[0] == 9 && i.coords[1] == 9;
});

【讨论】:

    【解决方案3】:

    从来没有听说过下划线js,所以我不能说它的细节。大多数 javacript 框架都有一种或另一种类型的 foreach 方法,用于模拟尚未标准化的 foreach 循环。

    function findMatches(/* target array*/ target, /* matching function*/ match) {
       var dummy = [];
       dojo.forEach(target, function(t) {
            if (match(t)) {
                dummy.push(t);
            }
       });
       return dummy;
    }
    
    var allMatches = findMatches(M, function (m) {
        m.text == "your mom" && m.coords == [9,9]
    });
    

    请注意,dojo.forEach 是我使用的 Dojo 库中的 forEach。 jQuery 还包含你喜欢的库中没有的这种东西。

    为时已晚,我还没有将这段代码放入实际的浏览器中,但这个想法是合理的,即使我打错了。

    【讨论】:

    • 我看到一些下划线专家已经过去了,所以在那个库中有一个更简单的方法。我将把这个答案留在这里,因为展示 find 类型方法是如何实现的可能会很有趣。
    • 感谢 sn-p @SAJ14SAJ,关于如何解决问题的观点越多越好;)
    【解决方案4】:

    使用 _.filter 方法。

    var filtered = _.filter(M, function(i) { return (i.text == "text2" && i.cords[0] == 3 && i.cords[1] == 4) });
    

    【讨论】:

    • @Xymotech,是的,它不起作用,因为数组相等不能那样工作。我只是想强调 _.filter 功能。但现在它应该可以工作了。检查这个小提琴:jsfiddle.net/BuddhiP/QMLVb/1
    • 为什么要强调_.filter函数? _.find 不够好用吗?
    • @Xymotech,well find 返回第一个,filter 返回所有匹配项。做你的选择。 :)
    【解决方案5】:

    到目前为止,所有其他答案都是使用第三方 js 库。以下是对直接 js 解决方案的尝试。小提琴:http://jsfiddle.net/rNfph/

    var M = [
        {text:'one', coord: [0,0]},
        {text:'two', coord: [1,1]},
        {text:'three', coord: [2,2]},
        {text:'four', coord: [3,3]},
        {text:'five', coord: [4,4]},
        {text:'six', coord: [5,5]},
        {text:'seven', coord: [6,6]},
        {text:'eight', coord: [7,7]},
        {text:'nine', coord: [8,8]},
        {text:'ten', coord: [9,9]}
    ];
    
    var search = function(str, x, y){
    
        for(var i=0, len=M.length; i<len; i++){
            if( M[i].text === str && M[i].coord[0] === x && M[i].coord[1] === y ){
                return true;
            }
        }
        return false;
    
    }
    
    console.log( search('three', 2, 2) );
    console.log( search('three', 1, 2) );
    

    现在,把这个和一粒盐一起吃吧。我不是复杂性方面的专家。很可能有更好的方法来做到这一点,因为这种实现可能需要遍历所有值。

    如果对此有限制,即“文本”的值必须是唯一的,那么您可以将其全部构建为对象(字典),而不是使用数组,并在不需要 的情况下进行检查任何次迭代。

    看到这个小提琴:http://jsfiddle.net/4mrsh/

    var M = {
        'one': [0,0],
        'two': [1,1],
        'three': [2,2],
        'four': [3,3]
    }
    
    var search = function(key, x, y){
    
        if( !M[key] || !(M[key][0] === x && M[key][1] === y) ) return false;
    
        return true;
    }
    
    console.log( search('three',2,2) ); //true
    console.log( search('three',1,2) ); //false
    

    【讨论】:

      【解决方案6】:
      if (!Array.prototype.each) {
         Array.prototype.each = function(callback) {
            var i, l = this.length;
            for (i = 0; i < l; i += 1) {
               if (callback(i, this[i]) === true) return;
            }
         }
      }
      
      function anMHasYourMom(m) {
         var found;
         m.each(function(i, el) {
            return found = (
               el.text === "your mom"
               && el.coords[0] === 9
               && el.coords[1] === 9
            );
         });
         return found;
      }
      
      var M = [A_1, A_2, ..., A_n];
      if (anMHasYourMom(M)) {
         window.alert('It has one!');
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-09
        • 2021-03-12
        • 1970-01-01
        • 2017-02-08
        • 2019-03-31
        • 1970-01-01
        • 2010-09-13
        相关资源
        最近更新 更多