2017-02-20 3 views
1

Каков наилучший способ найти индекс массива в коллекции массивов? Почему indexOf() не возвращает правильный индекс? Я предполагаю, что это связано с равенством объектов?Использование indexOf для получения индекса массива в массиве массивов (Javascript)

Я видел, как другие решения проходят через коллекцию и возвращают индекс, достигнутый при проверке равенства, но мне все же интересно узнать, почему indexOf() не делает то же самое. Кроме того, я не могу использовать ES6 find/findIndex из-за поддержки IE 11 (как всегда). Я включил свой тестовый код ниже. Большое спасибо.

var numbers = [ [1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12] ]; 
 

 
function getIndex (numbersToTest) { 
 
    return numbers.indexOf(numbersToTest); 
 
}; 
 

 
function test() { 
 
    console.log(getIndex([1, 2, 3, 4, 5, 6])); // Except 0 
 
    console.log(getIndex([7, 8, 9, 10, 11, 12])); // Expect 1 
 
    console.log(getIndex([2, 1, 3, 4, 5, 6])); // Expect -1 (not in same order) 
 
} 
 

 
test();

+0

Вы правы, что это имеет какое-то отношение к равенству объектов, потому что '[] == []' is 'false'. –

+0

У меня был ответ на этот вопрос, в этом случае можно было бы использовать сравнение массивов в виде строки, https://jsfiddle.net/dbpLenwu/ –

+0

@trincot Я не верю, что это дублированный вопрос, поскольку я искал лучший способ найти индекс массива, а также хотел получить некоторую справочную информацию о том, почему indexOf не работал (что не было основной точкой обсуждения). Большое спасибо. – poolts

ответ

1

Ссылки на объекты (включая ссылки массива) сравниваются в качестве эталонных значений; одна ссылка на объект равна другой, только если обе ссылки относятся к одному и тому же объекту. Сравнение не выполняется на основании содержимого массивов в вашем случае. Несмотря на то, что те массивы, которые вы передаете, имеют одинаковые значения, они представляют собой различные массивы и поэтому не равны ни одному из массивов в исходном списке.

Вместо этого вам нужно использовать что-то вроде Array#find (найти запись) или Array#findIndex (найти индекс данной записи), переходящую в обратном вызове, который сравнивает массив в numbers с numbersToTest, чтобы увидеть, если они эквивалентные массивы. This question's answers говорят о различных способах эффективного сравнения массивов для эквивалентности.

Например:

var numbers = [ [1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12] ]; 
 

 
function getIndex (numbersToTest) { 
 
    return numbers.findIndex(function(entry) { 
 
    // Simple comparison that works for an array of numbers 
 
    return entry.length === numbersToTest.length && entry.every(function(number, index) { 
 
     return numbersToTest[index] === number; 
 
    }); 
 
    }); 
 
}; 
 

 
function test() { 
 
    console.log(getIndex([1, 2, 3, 4, 5, 6])); // Expect 0 
 
    console.log(getIndex([7, 8, 9, 10, 11, 12])); // Expect 1 
 
    console.log(getIndex([2, 1, 3, 4, 5, 6])); // Expect -1 (not in same order) 
 
} 
 

 
test();

Обратите внимание, что оба Array#find и Array#findIndex являются довольно новыми (ES2015, ака "ES6"), но может быть polyfilled для старых двигателей JavaScript.

+0

Спасибо @TJCrowder Я должен вам пиво :) – Pointy

Смежные вопросы