it-roy-ru.com

Как найти индекс всех вхождений элемента в массиве?

Я пытаюсь найти индекс всех экземпляров элемента, скажем, «Nano», в массиве JavaScript.

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

Я попытался jQuery.inArray или аналогично .indexOf () , но он дал только индекс последнего экземпляра элемента, то есть 5 в этом случае.

Как мне получить его для всех случаев?

70
norbdum

Метод .indexOf() имеет необязательный второй параметр, который указывает индекс для начала поиска, поэтому вы можете вызвать его в цикле, чтобы найти все экземпляры определенного значения:

function getAllIndexes(arr, val) {
    var indexes = [], i = -1;
    while ((i = arr.indexOf(val, i+1)) != -1){
        indexes.Push(i);
    }
    return indexes;
}

var indexes = getAllIndexes(Cars, "Nano");

Вы не совсем понимаете, как вы хотите использовать индексы, поэтому моя функция возвращает их в виде массива (или возвращает пустой массив, если значение не найдено), но вы можете сделать что-то еще с отдельными значениями индекса внутри петли.

ОБНОВЛЕНИЕ: Согласно комментарию VisioN, простой цикл for будет выполнять ту же работу более эффективно, и его легче понять и, следовательно, легче поддерживать:

function getAllIndexes(arr, val) {
    var indexes = [], i;
    for(i = 0; i < arr.length; i++)
        if (arr[i] === val)
            indexes.Push(i);
    return indexes;
}
83
nnnnnn

Другое альтернативное решение - использовать Array.prototype.reduce() :

["Nano","Volvo","BMW","Nano","VW","Nano"].reduce(function(a, e, i) {
    if (e === 'Nano')
        a.Push(i);
    return a;
}, []);   // [0, 3, 5]

N.B .: Проверьте совместимость браузера для метода reduce и используйте polyfill при необходимости.

51
VisioN

Другой подход с использованием Array.prototype.map () и Array.prototype.filter () :

var indices = array.map((e, i) => e === value ? i : '').filter(String)
30
yckart

Примечание: MDN дает метод с использованием цикла while :

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
  indices.Push(idx);
  idx = array.indexOf(element, idx + 1);
}

Я бы не сказал, что это лучше, чем другие ответы. Просто интересно.

3
abalter

Более простой способ в стиле es6.

const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);


//Examples:
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
indexOfAll(cars, "Nano"); //[0, 3, 5]
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
2
Alex Petre

Это сработало для меня:

let array1 = [5, 12, 8, 130, 44, 12, 45, 12, 56];
let numToFind = 12
let indexesOf12 = [] // the number whose occurrence in the array we want to find

array1.forEach(function(elem, index, array) {
    if (elem === numToFind) {indexesOf12.Push(index)}
    return indexesOf12
})

console.log(indexesOf12) // outputs [1, 5, 7]
1
Jona Dev

Просто чтобы поделиться другим методом, вы можете использовать Генераторы функций для достижения результата:

function findAllIndexOf(target, needle) {
  return [].concat(...(function*(){
    for (var i = 0; i < target.length; i++) if (target[i] === needle) yield [i];
  })());
}

var target = "hellooooo";
var target2 = ['w','o',1,3,'l','o'];

console.log(findAllIndexOf(target, 'o'));
console.log(findAllIndexOf(target2, 'o'));
0
briosheje

Мы можем использовать Stack и помещать «i» в стек каждый раз, когда сталкиваемся с условием «arr [i] == value»

Проверь это:

static void getindex(int arr[], int value)
{
    Stack<Integer>st= new Stack<Integer>();
    int n= arr.length;
    for(int i=n-1; i>=0 ;i--)
    {
        if(arr[i]==value)
        {
            st.Push(i);
        }
    }   
    while(!st.isEmpty())
    {
        System.out.println(st.peek()+" ");
        st.pop(); 
    }
}
0
S Banzal

Я просто хочу обновить другим простым способом.

Вы также можете использовать метод forEach.

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

var result = [];

Cars.forEach((car, index) => car === 'Nano' ? result.Push(index) : null)
0
Ted Khi

Вы можете написать довольно простое удобочитаемое решение, используя map и filter:

const nanoIndexes = Cars
  .map((car, i) => car === 'Nano' ? i : -1)
  .filter(index => index !== -1);
0
Zac Delventhal