I am trying to find the indexes of all the instances of an element, say, “Nano”, in a JavaScript array.
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
I tried jQuery.inArray, or similarly, .indexOf(), but it only gave the index of the last instance of the element, i.e. 5 in this case.
How do I get it for all instances?
asked Dec 27, 2013 at 9:52
The .indexOf()
method has an optional second parameter that specifies the index to start searching from, so you can call it in a loop to find all instances of a particular value:
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");
You don’t really make it clear how you want to use the indexes, so my function returns them as an array (or returns an empty array if the value isn’t found), but you could do something else with the individual index values inside the loop.
UPDATE: As per VisioN’s comment, a simple for loop would get the same job done more efficiently, and it is easier to understand and therefore easier to maintain:
function getAllIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++)
if (arr[i] === val)
indexes.push(i);
return indexes;
}
answered Dec 27, 2013 at 9:59
nnnnnnnnnnnn
147k30 gold badges199 silver badges239 bronze badges
14
Another alternative solution is to use 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.: Check the browser compatibility for reduce
method and use polyfill if required.
answered Dec 27, 2013 at 10:10
VisioNVisioN
143k32 gold badges280 silver badges279 bronze badges
7
More simple way with es6 style.
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); // []
answered Oct 25, 2018 at 8:20
awmidasawmidas
6435 silver badges13 bronze badges
You can write a simple readable solution to this by using both map
and filter
:
const nanoIndexes = Cars
.map((car, i) => car === 'Nano' ? i : -1)
.filter(index => index !== -1);
EDIT: If you don’t need to support IE/Edge (or are transpiling your code), ES2019 gave us flatMap, which lets you do this in a simple one-liner:
const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);
answered Mar 2, 2019 at 2:32
Zac DelventhalZac Delventhal
3,4532 gold badges20 silver badges26 bronze badges
2
I just want to update with another easy method.
You can also use forEach method.
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
var result = [];
Cars.forEach((car, index) => car === 'Nano' ? result.push(index) : null)
answered Feb 12, 2019 at 11:21
JKhanJKhan
1,1474 gold badges14 silver badges23 bronze badges
Note: MDN gives a method using a while loop:
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);
}
I wouldn’t say it’s any better than other answers. Just interesting.
answered May 16, 2018 at 17:53
abalterabalter
9,48517 gold badges89 silver badges142 bronze badges
const indexes = cars
.map((car, i) => car === "Nano" ? i : null)
.filter(i => i !== null)
answered Jun 16, 2019 at 5:54
Michael PearsonMichael Pearson
5641 gold badge4 silver badges10 bronze badges
3
This worked for me:
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]
answered Feb 10, 2019 at 3:05
Just to share another method, you can use Function Generators to achieve the result as well:
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'));
answered May 15, 2019 at 9:08
brioshejebriosheje
7,2982 gold badges32 silver badges53 bronze badges
["a", "b", "a", "b"]
.map((val, index) => ({ val, index }))
.filter(({val, index}) => val === "a")
.map(({val, index}) => index)
=> [0, 2]
answered Nov 21, 2019 at 17:55
Dávid KonkolyDávid Konkoly
1,6951 gold badge12 silver badges8 bronze badges
1
You can use Polyfill
if (!Array.prototype.filterIndex)
{
Array.prototype.filterIndex = function (func, thisArg) {
'use strict';
if (!((typeof func === 'Function' || typeof func === 'function') && this))
throw new TypeError();
let len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
let kValue;
if (thisArg === undefined) {
while (++i !== len) {
// checks to see if the key was set
if (i in this) {
kValue = t[i]; // in case t is changed in callback
if (func(t[i], i, t)) {
res[c++] = i;
}
}
}
}
else {
while (++i !== len) {
// checks to see if the key was set
if (i in this) {
kValue = t[i];
if (func.call(thisArg, t[i], i, t)) {
res[c++] = i;
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
Use it like this:
[2,23,1,2,3,4,52,2].filterIndex(element => element === 2)
result: [0, 3, 7]
answered May 17, 2020 at 8:19
We can use Stack and push “i” into the stack every time we encounter the condition “arr[i]==value”
Check this:
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();
}
}
answered Mar 27, 2018 at 4:29
1
When both parameter passed as array
function getIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++){
for(j =0; j< val.length; j++) {
if (arr[i] === val[j])
indexes.push(i);
}
}
return indexes;
}
answered Mar 30, 2021 at 10:07
Also, findIndex() will be useful:
var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];
const indexes = [];
const searchedItem = 'NaNo';
cars.findIndex((value, index) => {
if (value.toLowerCase() === searchedItem.toLowerCase()) {
indexes.push(index);
}
});
console.log(indexes); //[ 0, 3, 5 ]
Bonus:
This custom solution using Object.entries()
and forEach()
var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];
const indexes = [];
const searchableItem = 'Nano';
Object.entries(cars).forEach((item, index) => {
if (item[1].toLowerCase() === searchableItem.toLowerCase())
indexes.push(index);
});
console.log(indexes);
Note: I did not run run all tests
answered Dec 19, 2022 at 19:52
findIndex
retrieves only the first index which matches callback output. You can implement your own findIndexes
by extending Array , then casting your arrays to the new structure .
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'))
)
answered Aug 12, 2017 at 2:32
Abdennour TOUMIAbdennour TOUMI
85.2k38 gold badges242 silver badges250 bronze badges
Given an array arr[] of integers of size N and a target value val. Your task is to find the indices of val in the array after sorting the array in increasing order.
Note: The indices must be in increasing order.
Examples:
Input: arr = [1, 2, 5, 2, 3], val = 2
Output: 1 2
Explanation: After sorting, arr[] becomes [1, 2, 2, 3, 5]. The indices where arr[i] = 2 are 1 and 2. As the indices should be in increasing order, that’s why they are (1, 2) and not (2, 1)Input: arr = [1, 2, 5, 2, 3], val = 6
Output: []
Explanation: After sorting, nums is [1, 2, 2, 3, 5]. The value 6 is not present in the array.
Naive Approach: The concept of this approach is based on sorting. The array is sorted in increasing order. Then the sorted array is traversed. While traversing the array if any value matches the target, that index is added to the answer list. After the iteration is complete the answer list is returned.
Time Complexity: O(N*logN)
Auxiliary Space: O(1)
Efficient Approach: This approach is based on the observation of a sorted array. In an array which is sorted in increasing order all the elements before val are less than val. So, to get the indices of val in a sorted array, instead of performing sort operation, we can simply count the elements less than val. If the count is x then val will start from x-th index (because of 0-based indexing). Follow the steps mentioned below:
- Traverse the array. Use variables to store the count of elements less than val (smallCount) and elements having a value same as val (sameCount).
- If the value of an element is less than val increment smallCount by one.
- If the value is same as val increment sameCount by one.
- After traversal is complete, the indices will start from smallCount and end at (smallCount+sameCount-1)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using
namespace
std;
vector<
int
> targetIndices(vector<
int
>& nums,
int
val)
{
int
count_less = 0;
int
count_target = 0;
for
(
auto
& it : nums) {
if
(it == val)
count_target++;
if
(it < val)
count_less++;
}
vector<
int
> ans;
while
(count_target--) {
ans.push_back(count_less++);
}
return
ans;
}
int
main()
{
vector<
int
> nums{ 1, 2, 5, 2, 3 };
int
val = 2;
vector<
int
> ans = targetIndices(nums, val);
for
(
int
i = 0; i < ans.size(); i++) {
cout << ans[i] <<
" "
;
}
return
0;
}
Java
import
java.util.*;
public
class
GFG {
static
List<Integer> targetIndices(
int
[] nums,
int
val)
{
int
count_less =
0
;
int
count_target =
0
;
for
(
int
i =
0
; i < nums.length; i++) {
if
(nums[i] == val)
count_target++;
if
(nums[i] < val)
count_less++;
}
List<Integer> ans =
new
ArrayList<Integer>();
while
(count_target >
0
) {
ans.add(count_less++);
count_target--;
}
return
ans;
}
public
static
void
main(String args[])
{
int
[] nums = {
1
,
2
,
5
,
2
,
3
};
int
val =
2
;
List<Integer> ans = targetIndices(nums, val);
for
(
int
i =
0
; i < ans.size(); i++) {
System.out.print(ans.get(i) +
" "
);
}
}
}
Python3
def
targetIndices(nums, val):
count_less
=
0
count_target
=
0
for
i
in
range
(
len
(nums)):
if
(nums[i]
=
=
val):
count_target
+
=
1
if
(nums[i] < val):
count_less
+
=
1
ans
=
[]
while
(count_target):
ans.append(count_less)
count_less
+
=
1
count_target
-
=
1
return
ans
nums
=
[
1
,
2
,
5
,
2
,
3
]
val
=
2
ans
=
targetIndices(nums, val)
for
i
in
range
(
len
(ans)):
print
(ans[i], end
=
" "
)
C#
using
System;
using
System.Collections;
using
System.Collections.Generic;
class
GFG {
static
ArrayList targetIndices(
int
[] nums,
int
val)
{
int
count_less = 0;
int
count_target = 0;
for
(
int
i = 0; i < nums.Length; i++) {
if
(nums[i] == val)
count_target++;
if
(nums[i] < val)
count_less++;
}
ArrayList ans =
new
ArrayList();
while
(count_target > 0) {
ans.Add(count_less++);
count_target--;
}
return
ans;
}
public
static
void
Main()
{
int
[] nums = { 1, 2, 5, 2, 3 };
int
val = 2;
ArrayList ans = targetIndices(nums, val);
for
(
int
i = 0; i < ans.Count; i++) {
Console.Write(ans[i] +
" "
);
}
}
}
Javascript
<script>
function
targetIndices(nums, val)
{
let count_less = 0;
let count_target = 0;
for
(let i = 0; i < nums.length; i++) {
if
(nums[i] == val)
count_target++;
if
(nums[i] < val)
count_less++;
}
let ans = [];
while
(count_target--) {
ans.push(count_less++);
}
return
ans;
}
let nums = [ 1, 2, 5, 2, 3 ];
let val = 2;
let ans = targetIndices(nums, val);
for
(let i = 0; i < ans.length; i++) {
document.write(ans[i] +
" "
);
}
</script>
Time Complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
19 Jul, 2022
Like Article
Save Article
В этом посте будет обсуждаться, как найти индекс всех вхождений элемента в списке Python.
1. Использование enumerate()
функция
Чтобы получить индекс всех вхождений элемента в список, вы можете использовать встроенную функцию enumerate(). Он был введен для решения задачи счетчика циклов и может использоваться следующим образом:
if __name__ == ‘__main__’: ints = [1, 3, 7, 5, 4, 3] item = 3 for index, elem in enumerate(ints): if elem == item: print(f“{item} is found at index {index}”) ”’ Output: 3 is found at index 1 3 is found at index 5 ”’ |
Скачать Выполнить код
Чтобы получить список всех индексов сразу, используйте понимание списка с функцией перечисления:
if __name__ == ‘__main__’: ints = [1, 3, 7, 5, 4, 3] item = 3 indexes = [i for i, j in enumerate(ints) if j == item] print(f“Item {item} is found at index {indexes}”) # результат: Item 3 is found at index [1, 5] |
Скачать Выполнить код
2. Использование range()
функция
В качестве альтернативы вы можете использовать range()
функция, чтобы получить список всех допустимых индексов, а затем сопоставить соответствующее значение, присутствующее в каждом индексе, с данным элементом.
if __name__ == ‘__main__’: ints = [1, 3, 7, 5, 4, 3] item = 3 indexes = [i for i in range(len(ints)) if ints[i] == item] print(f“Item {item} is found at index {indexes}”) # результат: Item 3 is found at index [1, 5] |
Скачать Выполнить код
Другой подход заключается в использовании count()
функционировать в itertools
, который создает итератор для эффективного цикла, чтобы возвращать равномерно распределенные значения, начиная с заданного числа. Вы можете использовать его с zip()
для добавления порядковых номеров следующим образом.
from itertools import count if __name__ == ‘__main__’: ints = [1, 3, 7, 5, 4, 3] item = 3 zipped = [(i, j) for i, j in zip(count(), ints) if j == item] print(zipped) # [(1, 3), (5, 3)] |
Скачать Выполнить код
The more-itertools
библиотека предоставляет элегантные подпрограммы для работы с итерируемыми объектами Python. Вы можете использовать more_itertools.locate функция, которая возвращает индекс каждого элемента в итерируемом объекте, для которого выполняется заданный предикат. Ниже приведен простой пример, демонстрирующий использование этой функции:
from more_itertools import locate if __name__ == ‘__main__’: ints = [1, 3, 7, 5, 4, 3] item = 3 indexes = list(locate(ints, lambda x: x == item)) print(f“Item {item} is found at index {indexes}”) # результат: Item 3 is found at index [1, 5] |
Скачать код
5. Использование NumPy
Библиотека
Наконец, если вы используете NumPy
уже и нужны все индексы, вы можете использовать numpy.where()
функция.
import numpy as np if __name__ == ‘__main__’: ints = [1, 3, 7, 5, 4, 3] item = 3 indexes = np.where(np.array(ints) == item)[0] print(f“Item {item} is found at index {indexes}”) # результат: Item 3 is found at index [1, 5] |
Это все, что касается поиска индекса всех вхождений элемента в списке в Python.
Четверг 11 / 11 / 3 Регистрация: 13.10.2016 Сообщений: 195 |
||||||||||||
1 |
||||||||||||
Как проще найти все индексы списка, кортежа по значению?27.08.2018, 14:01. Показов 11831. Ответов 2 Метки нет (Все метки)
В этом случае вернет число 1. Нет функции, чтоб вернул кортеж или список из все индексов значений равных “30”, т.е. для этого примера 1 и 2.
Нет ничего покороче? Типа например four.find(’30’) или four.index_all(’30’) или еще как нибудь?
0 |
Garry Galler 5407 / 3831 / 1214 Регистрация: 28.10.2013 Сообщений: 9,554 Записей в блоге: 1 |
||||
27.08.2018, 14:19 |
2 |
|||
Сообщение было отмечено Четверг как решение Решение
Добавлено через 11 секунд
Нет ничего покороче? Нет. Разве что в numpy функциях.
1 |
Vigi 628 / 468 / 179 Регистрация: 28.05.2012 Сообщений: 1,398 |
||||
28.08.2018, 12:41 |
3 |
|||
Если хотите в коде использовать не единожды и покороче напишите свою функцию (взять из примера Garry Galler)
0 |
Как найти индексы всех вхождений элемента в массиве?
Я пытаюсь найти индекс всех экземпляров элемента, скажем, “Nano”, в массиве JavaScript.
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
пробовал jQuery.inArray, или аналогично, .indexOf (), но он только дал индекс последнего вхождения элемента, т. е. 5 в этом случае.
Как я могу получить его для всех экземпляров?
1196
7
7 ответов:
The
.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; }
еще одно альтернативное решение-использовать
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
метод и использовать полифилл если требуется.
Примечание: 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); }
Я бы не сказал, что это лучше, чем другие ответы. Просто интересно.
мы можем использовать стек и нажимать “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(); } }
findIndex
получает только первый индекс, который соответствует выходу обратного вызова. Вы можете реализовать свой собственныйfindIndexes
путем расширения массива, а затем приведения массивов к новой структуре .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')) )
Если вы собираетесь использовать подчеркивание / 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]