2013-10-24 42 views
1

是否可以使用array.indexOf作为searchElement传递一个对象。在我的例子中,结果是-1。是否可以使用`array.indexOf`作为`searchElement`传递一个对象?

var myArray = [{id: 1, name: 'milan'}, {id: 2, name: 'rome'}]; 
    var idx = myArray.indexOf({id: 1, name: 'milan'}); 

如果不行可以采用哪种更快的替代方法?也许使用array.filter并作为结果值返回索引?

+3

可以将indexOf与对象一起使用,但它需要是同一个对象(不是具有相同属性/值的对象),即'myArray.indexOf(myArray [0])=== 0' – Niklas

+0

你能为我提供一个例子吗? – GibboK

+0

这可能有助于:http://stackoverflow.com/questions/8668174/indexof-method-in-an-object-array –

回答

1

这是不可能的,因为对象与引用相等语义进行比较;两个不同实例的相同对象将比较不相等。这意味着无论如何,您都需要编写用于比较的定制逻辑。

在一般情况下,您可以通过迭代每个属性并测试每个属性是否存在,并且在候选数组元素上具有相同的值(很可能需要递归)来找到该对象。根据对象可能包含的内容,比较方法也需要识别数组。

对于极其简单的情况,例如{id: 1},您也可以通过在输入和每个元素上使用JSON.stringify来快速肮脏地对其进行破解并比较结果。

0

array.filter()方法不返回它只是提供索引来过滤数据的索引,但它总是返回一个数组的整个对象谁满足.filter()

可以使用该逻辑条件

function getIndex(myArray, element) 
{ 
    for(var i=0; i<array.length; i++) { 
     if(element.id == myArray[i].id) 
      return i; 
    } 
    return -1; 
} 
1

没有,但你可以过滤出...

var myArray = [{id: 1, name: 'milan'}, {id: 2, name: 'rome'}], 
    equals = function equals(o1, o2) { 
     return o1.id == o2.id && o1.name == o2.name; 
    }, 
    idx = {id: 1, name: 'milan'}, 
    filtered = myArray.filter(function(object, index,array1) { 
     return equals(idx, object); 
    }); 
+0

我明白你的观点,请看看它在代码中有一个错误,因为o .id没有定义,使用对象代替 – GibboK

+0

我修复了代码。我传递了'object'来解决实例问题,但代码中有'o' ......它现在应该可以工作了。你可以使它成为一个命名函数,并在需要它的地方使用它或提供一个“等于(o1,o2)”。我会在几分钟内编辑它。 –

1

不,你不能使用indexOf为:它采用strict equality为C比较,因此:

console.log({id: 1, name: 'milan'} === {id: 1, name: 'milan'}); // false 

因为它们是两个不同的对象,它包含相同的属性。

在不远的未来,你将能够使用新的ES6阵列的方法,像findfindIndex(他们在Firefox Nightly已经实施为例):

var myArray = [{id: 1, name: 'milan'}, {id: 2, name: 'rome'}]; 
var idx = myArray.findIndex(({id}) => id === 1); // `idx` will be `0` 
var item = myArray.find(({id}) => id === 1); // `item` will contains {id: 1, name: 'milan'} 

在此同时,你有手动做到这一点;如果你想比较所有的属性更好,如果你创建一个deepEqual函数或类似的。

相关问题