2014-11-04 145 views

回答

4

你必须循环一次。但是你可以抽象它看起来像你不循环

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; 
 
}));

正如安东尼所说,这是建议的ECMAScript 6.下面是更完整的填充工具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; 
})); 
+0

MDN列出了一个实验/建议的数组迭代函数,['findIndex()'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) ,这似乎是一回事。现在肯定想为自己实现这样的事情,但也许在某个时候不需要。 – 2014-11-04 15:39:56

0

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

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)); 
+0

这是一个糟糕的抽象,如果你想在不同的属性或不同的值上搜索,你必须用新的循环编写一个新的函数 – 2014-11-04 15:35:17

+0

好点。但它是一个简单的解决ops麻烦的意思来说明他需要做的事情 – Goodword 2014-11-04 15:37:36

+0

我不认为OP不知道如何使用for循环。看到我的解决方案可重用函数http://stackoverflow.com/a/26739030/227299 – 2014-11-04 15:38:13

0

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

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

你可以使用Array.forEach我猜

var fooArray = [{id:1, value:5},{id:2, value:6},{id:3, value:7},{id:4, value:8}]; 
var foundIndex = -1; 
fooArray.forEach(function(el, index){ 
    if(el.id==3) { 
     foundIndex=index; 
     return false; 
    }; 
}); 

//foundIndex = 2 
+0

太快保存了:o) – 2014-11-04 15:43:55

+0

现在它确实工作:) forEach与循环没有多大区别,是吗?我知道我的答案也会循环,但至少我建议一种策略,不要求您每次要搜索不同的属性或值时使用回调编写循环代码,使用回调 – 2014-11-04 15:53:14

0

您可以使用滤镜阵列,但我认为你会使用一个循环得到较好的解决。

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); 
+1

谁高举此举?这将返回一个数组,其中包含满足条件的对象,但不会返回从回调中返回的索引。更糟糕的是,当第一个项目符合条件时,甚至无法正确过滤。 – 2014-11-04 15:48:31

0
arrayElements.map(o => o.id).indexOf(3); 

注:

  • 可能比一个循环,因为之前 搜索变换整个阵列慢。但是用Javascript等高级语言,你永远不知道 。
  • 无限可读比循环。
  • IE兼容(不同于2017年的findIndex)。
+0

感谢您的回答,但该死的,这个问题是两岁了......:D – 2017-02-14 13:39:57

+0

@JulianBerger:** 1。**好的问题是永恒的。 ** 2。**你说话像个凡人。两年对我们来说没有任何意义。我们已经回答了两千年的问题。 ** 3。**我很高兴你还活着。一百年后,当我们回答您的问题时,我们可能不会那么幸运。我们仍然会尝试。 ** 4。** * Quid biennium adæonem?在ævi?在Terrae鼹鼠中的Quanta套管,在Oceano中的Quanta gutta,在Sole exicum est两年期期间在ævi的Quanta scintilla。* – 7vujy0f0hy 2017-03-29 06:05:43