【问题标题】:indexOf() when array-elements are objects (javascript)indexOf() 当数组元素是对象时(javascript)
【发布时间】:2014-11-04 15:21:27
【问题描述】:

例如,名为 arrayElements 的数组类型变量包含:
[{id:1, value:5},{id:2, value:6},{id:3, value:7},{id:4, value:8}]。

除了使用循环之外,如何在arrayElements 变量中获取带有id === 3(第3 个元素)的数组元素的位置?

谢谢。

【问题讨论】:

    标签: javascript arrays indexof


    【解决方案1】:

    你必须在某一点循环。但是您可以将其抽象为看起来没有循环

    function indexOfCallback(arr, callback, startIndex) {
        if (typeof startIndex == 'undefined') {
            startIndex = 0;
        }
        for(var i=startIndex; i < arr.length; i ++) {
            if (callback(arr[i])) {
                return i;
            }
        }
        return -1;
    }
    
    var array = [{id:1, value:5},{id:2, value:6},{id:3, value:7},{id:4, value:8}];
    // Search on id === 3
    console.log(indexOfCallback(array, function(obj){
        return obj.id === 3;
    }));
    // Search on value === 6
    console.log(indexOfCallback(array, function(obj){
        return obj.value === 6;
    }));

    正如 Anthony 所说,这是针对 ECMAScript 6 提出的。这是更完整的 polyfill https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

    if (!Array.prototype.findIndex) {
      Array.prototype.findIndex = function(predicate) {
        if (this == null) {
          throw new TypeError('Array.prototype.find called on null or undefined');
        }
        if (typeof predicate !== 'function') {
          throw new TypeError('predicate must be a function');
        }
        var list = Object(this);
        var length = list.length >>> 0;
        var thisArg = arguments[1];
        var value;
    
        for (var i = 0; i < length; i++) {
          value = list[i];
          if (predicate.call(thisArg, value, i, list)) {
            return i;
          }
        }
        return -1;
      };
    }
    console.log(array.findIndex(function(obj){
        return obj.id === 3;
    }));
    

    【讨论】:

    • MDN 有一个实验/提议的数组迭代函数列表,findIndex(),这似乎是同一件事。现在肯定想为自己实现这样的东西,但也许在某些时候不需要。
    【解决方案2】:
    arrayElements.map(o => o.id).indexOf(3);
    

    注意事项:

    • 可能比循环慢,因为在之前转换整个数组 搜索。但是对于像 Javascript 这样的高级语言,你永远不会 知道。
    • 比循环更具可读性。
    • IE 兼容(与 2017 年的 findIndex 不同)。

    【讨论】:

    • 感谢您的回答,但该死的,这个问题已经有两年历史了......:D
    • @JulianBerger:1. 好的问题是永恒的。 2. 你说话像个凡人。两年对我们来说不算什么。我们已经回答了两 千 年前的问题。 3. 我很高兴你还活着。一百年后,当我们回答你的问题时,我们可能就没有那么幸运了。不过,我们仍然会尝试。 4. Quid bienium ad æonem? Quid est hoc in die ævi? Terrae mole 中的 Quanta areula,Oceano 中的 quanta gutta,Sole 中的 quanta scintilla – sic exiguum est binnium in die ævi。
    【解决方案3】:

    在这样的数组中,您不能通过 id 访问元素。因此,使用循环是您拥有的最佳解决方案。但是,根据您的用例,您也可以考虑使用对象而不是数组进行直接访问。

    var container = { 1: {id:1, value:5}, 2: {id:2, value:6}, 3: {id:3, value:7} }
    

    【讨论】:

      【解决方案4】:

      您可以使用数组过滤器,但我认为使用循环可以获得更好的解决方案。

      var array = [{id:1, value:5},{id:2, value:6},{id:3, value:7},{id:4, value:8}];
      
      var result = array.filter(condition);
      
      function condition(value, index){
          if (value.id === 3) return index;
      }
      
      console.log(result);
      

      【讨论】:

      • 谁赞成这个?这将返回一个包含满足条件的对象的数组,它不返回从回调返回的索引。更糟糕的是,当第一项匹配条件时,这甚至无法正确过滤。
      【解决方案5】:

      我为你写了一个函数,你可以使用它来完成工作,但它使用了一个循环:

      var yourObjArray = [{id:1, value:5},{id:2, value:6},{id:3, value:7},{id:4, value:8}];
      
      
      function objArrayIndex(objArray){
        for(var i = 0; i < objArray.length; i++){
          if(objArray[i]['id'] == 3){
            return i;
          }
        }
        return -1;
      }
      
      console.log(objArrayIndex(yourObjArray));
      

      【讨论】:

      • 这是一个糟糕的抽象,如果你想搜索不同的属性或不同的值,你必须编写一个带有新循环的新函数
      • 好点。但这是解决运营问题的简单方法,旨在说明他需要做的事情
      • 我认为 OP 不知道如何使用 for 循环。请参阅我的可重用函数解决方案stackoverflow.com/a/26739030/227299
      • 很难说为什么 OP 不想使用循环,但我已经编辑了我的答案以去掉“抽象”这个词。
      • 我实际上认为 OP 正在寻找抽象。他们想要indexOf 之类的东西,它允许您通过指定要查找的内容作为参数来搜索数组,但在这种情况下,您不能只传递一个类似的对象,因为它们不会通过相等测试。解决方案是让调用者将相等函数实现为回调。再次,请参阅我的答案。
      猜你喜欢
      • 2012-01-08
      • 2017-05-31
      • 2020-09-28
      • 2015-04-22
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多