Почему indexOf() возвращает -1 при правильном значении?

У меня есть цикл for, который добавляет из отдельных списков в один с именем $scope.stats

for (var i = 0; i < $scope.totalNames.length; i++) {
    var list = $scope.totalNames[i];
    for (var j = 0; j < list.length; j++) {
        var quote = list[j].quote;
        if (typeof localStorage[quote] == "undefined") {
            localStorage[quote] = 0;
        }
        $scope.stats.pushUnique({quote: quote, value: localStorage[quote]});
    }
}

Этот код работает. Проблема заключается ниже, где indexOf возвращает -1, хотя я проверил, и {quote: quote, value: localStorage[quote]} - это то же самое значение, что и элемент в списке.

//below is stated in a function where the quote var has the same value as quote var above

var index = $scope.stats.indexOf({quote: quote, value: localStorage[quote]}, 0);

alert(index); //returns -1

person benjipelletier    schedule 24.05.2014    source источник
comment
Вы пытаетесь использовать indexOf для массива объектов, который работает не так, как вы могли ожидать. Это возможный дубликат метода indexOf в массиве объектов? и Javascript array.indexOf не ищет объекты   -  person Nope    schedule 24.05.2014
comment
Отлично, спасибо, это сработало!   -  person benjipelletier    schedule 24.05.2014


Ответы (3)


Это потому, что 2 объекта не одинаковы. Вы не можете сравнить 2 объекта, используя сравнение ==. Возьмите этот уменьшенный пример:

[{a:'b'}].indexOf({a:'b'}); // returns -1

Это связано с тем, что оба этих объекта, несмотря на одинаковое содержимое, имеют разные идентификаторы объектов, прикрепленные к ним для JavaScript. Объекты относятся к разным объектам, поэтому .indexOf не может найти объект с идентификатором x в массиве, который содержит только объект с идентификатором y.

Однако вы можете использовать indexOf, если в качестве аргумента указываете тот же самый объект. Например:

var obj = {a:'b'};
[obj, 1, 2, 3].indexOf(obj); //returns 0

Потому что тогда он ищет объект с идентификатором x, который действительно присутствует в этом массиве.

person Joeytje50    schedule 24.05.2014

Когда вы запрашиваете indexOf объекта, {quote: quote, value: localStorage[quote]}, он ищет ссылку на этот конкретный объект (который был только что создан при вашем вызове indexOf), но вам нужно найти индекс любого объекта с quote: quote и value: localStorage[quote].

var found = $scope.stats.filter(function(stat){ return stat.quote == quote && stat.value == localStorage[quote]; });
var index = -1;
if(found.length > 0)
   index = $scope.stats.indexOf(found[0]);

Это позволит получить ссылку на объект первого элемента, который соответствует кавычке: цитата и значение: localStorage[quote], а затем найти индекс этого элемента в массиве.

person Clint Powell    schedule 24.05.2014

Эта пользовательская функция решила мою проблему:

    $scope.arrayObjectIndexOf = function(myArray, property, searchTerm){
    for(var i = 0, len = myArray.length; i < len; i++) {
        if (myArray[i][property] === searchTerm) return i;
    }
    return -1;
}
person benjipelletier    schedule 24.05.2014