Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

Метод .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, простой цикл цикла будет выполнять ту же работу более эффективно, и ее легче понять и, следовательно, легче поддерживать:

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

Ответ 2

Другим альтернативным решением является использование 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]

NB: Проверьте совместимость браузера для метода reduce и используйте polyfill, если требуется.

Ответ 4

Примечание: 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);
}

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

Ответ 5

Более простой способ в стиле 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); // []

Ответ 6

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

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

РЕДАКТИРОВАТЬ: Если вам не нужно поддерживать IE/Edge (или переносите ваш код), ES2019 предоставил нам flatMap, который позволяет вам сделать это простым однострочным:

const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);

Ответ 7

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

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

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

var result = [];

Cars.forEach((car, index) => car === 'Nano' ? result.push(index) : null)

Ответ 8

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

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]

Ответ 9

const indexes = cars
    .map((car, i) => car === "Nano" ? i : null)
    .filter(i => i !== null)

Ответ 10

С JQuery: FIDDLE Посмотрите на журнал консоли

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

function getCarsPosition(carsTab, carName){
    var t = [];
    $.each(carsTab , function(index, val) { 
        if(val === carName){
            t.push(index)
        }

    });
    console.log(t)
    return t;
}

getCarsPosition(Cars, "Nano");

Ответ 11

Мы можем использовать 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(); 
    }
}

Ответ 12

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

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

Ответ 13

findIndex извлекает только первый индекс, который соответствует выходному сигналу обратного вызова. Вы можете реализовать свой собственный findIndexes, расширив Array, а затем переведя ваши массивы в новую структуру.

class EnhancedArray extends Array {
  findIndexes(where) {
    return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []);
  }
}
   /*----Working with simple data structure (array of numbers) ---*/

//existing array
let myArray = [1, 3, 5, 5, 4, 5];

//cast it :
myArray = new EnhancedArray(...myArray);

//run
console.log(
   myArray.findIndexes((e) => e===5)
)
/*----Working with Array of complex items structure-*/

let arr = [{name: 'Ahmed'}, {name: 'Rami'}, {name: 'Abdennour'}];

arr= new EnhancedArray(...arr);


console.log(
  arr.findIndexes((o) => o.name.startsWith('A'))
)

Ответ 14

Если вы намерены использовать подчеркивание /lodash, вы могли бы сделать

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

_.chain(Cars).map((v, i)=> [i, v === "Nano"]).filter(v=>v[1]).map(v=>v[0]).value()

[0, 3, 5]

Ответ 15

Обычная JS

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

for (var i = 0; i < Cars.length; i++) {
        console.log("Value: " + Cars[i] + ", Index: " + i);
}