Como encontrar o índice de todas as ocorrências de elemento na matriz?

Eu estou tentando encontrar o índice de todas as instâncias de um elemento, digamos, “Nano”, em uma matriz de JavaScript.

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

Eu tentei jQuery.inArray , ou similarmente, .indexOf () , mas só deu o índice da última instância do elemento, ou seja, 5 neste caso.

Como obtenho para todas as instâncias?

O método .indexOf() tem um segundo parâmetro opcional que especifica o índice para iniciar a pesquisa, portanto, você pode chamá-lo em um loop para localizar todas as instâncias de um valor específico:

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

Você não deixa claro como deseja usar os índices, então minha function os retorna como uma matriz (ou retorna uma matriz vazia se o valor não for encontrado), mas você poderia fazer outra coisa com os valores de índice individuais dentro do loop.

ATUALIZAÇÃO: De acordo com o comentário do VisioN, um loop for simples executaria o mesmo trabalho de maneira mais eficiente e seria mais fácil de entender e, portanto, mais fácil de manter:

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

Outra solução alternativa é usar 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: Verifique a compatibilidade do navegador para reduce método e use o polyfill, se necessário.

Outra abordagem usando Array.prototype.map () e Array.prototype.filter () :

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

Nota: O MDN fornece um método usando um loop 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); } 

Eu não diria que é melhor que outras respostas. Apenas interessante.

Podemos usar Stack e empurrar “i” na pilha toda vez que encontrarmos a condição “arr [i] == value”

Verifique isso:

 static void getindex(int arr[], int value) { Stackst= new Stack(); 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(); } } 

findIndex recupera apenas o primeiro índice que corresponde à saída de retorno de chamada. Você pode implementar seus próprios findIndexes estendendo Array e, em seguida, findIndexes seus arrays para a nova estrutura.

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

Se você pretende usar sublinhado / lodash, você poderia fazer

 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]