Как найти все индексы элемента в массиве

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?

Menai Ala Eddine - Aladdin's user avatar

asked Dec 27, 2013 at 9:52

norbdum's user avatar

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

nnnnnn's user avatar

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

VisioN's user avatar

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

awmidas's user avatar

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 Delventhal's user avatar

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

JKhan's user avatar

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

abalter's user avatar

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 Pearson's user avatar

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

Jona Dev's user avatar

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

briosheje's user avatar

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 Konkoly's user avatar

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

EbiPenMan's user avatar

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

S Banzal's user avatar

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

Minhal Kizhakkayil's user avatar

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

Menai Ala Eddine - Aladdin's user avatar

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 TOUMI's user avatar

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

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Python
1
four = ('10', '30', '30')
Python
1
print(four.index('30'))

В этом случае вернет число 1. Нет функции, чтоб вернул кортеж или список из все индексов значений равных “30”, т.е. для этого примера 1 и 2.
То что можно в цикле вот так я знаю:

Python
1
2
3
4
5
6
find_this = '30'
i = 0
for k in four:
    if k == find_this:
       print(k, i)
    i += 1

Нет ничего покороче? Типа например four.find(’30’) или four.index_all(’30’) или еще как нибудь?



0



Garry Galler

Эксперт Python

5407 / 3831 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

27.08.2018, 14:19

2

Лучший ответ Сообщение было отмечено Четверг как решение

Решение

Python
1
2
3
4
>>> four = ('10', '30', '30')
>>> [i for i,v in enumerate(four) if v=='30']
[1, 2]
>>>

Добавлено через 11 секунд

Цитата
Сообщение от Четверг
Посмотреть сообщение

Нет ничего покороче?

Нет. Разве что в numpy функциях.



1



Vigi

628 / 468 / 179

Регистрация: 28.05.2012

Сообщений: 1,398

28.08.2018, 12:41

3

Если хотите в коде использовать не единожды и покороче напишите свою функцию (взять из примера Garry Galler)
и все будет вам счастье:

Python
1
2
3
4
5
6
def index_all(lst: tuple, val: str):
    return [i for i, v in enumerate(lst) if v == val]
 
 
four = ('10', '30', '30')
print(index_all(four, '30'))



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]

Добавить комментарий