9

I have a 1 dimensional array like:

var abc = ['a','a','b','a','c']

Now I want to get back all the indexes of 'a', that is 0, 1 and 3.

Are there any simple solutions?

P.S.

I know IndexOf or jQuery.inArray(). But they just returned the index of first matched element only

iconoclast
  • 21,213
  • 15
  • 102
  • 138
Capitaine
  • 1,923
  • 6
  • 27
  • 46

10 Answers10

8

You could extend the basic Array Object with the following method:

Array.prototype.multiIndexOf = function (el) { 
    var idxs = [];
    for (var i = this.length - 1; i >= 0; i--) {
        if (this[i] === el) {
            idxs.unshift(i);
        }
    }
    return idxs;
};

Then the operation

var abc = ['a','a','b','a','c'];
abc.multiIndexOf('a');

would give you the result:

[0, 1, 3]

Jsperf comparison of unshift / push / push(reverse order)

Matyas
  • 13,473
  • 3
  • 60
  • 73
7

You could use Array#reduce with Array#concat with a check for the wanted item, take the index or an empty array.

var abc = ['a', 'a', 'b', 'a', 'c'],
    indices = abc.reduce((r, v, i) => r.concat(v === 'a' ? i : []), []);

console.log(indices);

ES5

var abc = ['a', 'a', 'b', 'a', 'c'],
    indices = abc.reduce(function (r, v, i) {
        return r.concat(v === 'a' ? i : []);
    }, []);

console.log(indices);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
5

Rather than using a for loop, you can use a while loop combined with indexOf:

var array = [1, 2, 3, 4, 2, 8, 5],
    value = 2,
    i = -1,
    indizes = [];

while((i = array.indexOf(value, i + 1)) !== -1) {
    indizes.push(i);
}

This will return you [1, 4] and of course could be combined with extending the prototype of Array.

The second argument of indexOf specifies where to start the search in the given array.

Sascha Wolf
  • 18,810
  • 4
  • 51
  • 73
4

You can take advantage of the fact that $.map() does not push values in its resulting array when the function you pass returns undefined.

Therefore, you can write:

var abc = ["a", "a", "b", "a", "c"];
var indices = $.map(abc, function(element, index) {
    if (element == "a") {
        return index;
    }
});
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
2

You also use reduce function on the array and push the indexes to accumulated array, you need start with an empty array, the good thing about reduce is it's async and also time execution is faster than for loop, also it's a native function on array, look at the below, hope it's helping:

 var arr = [0, 1, 2, 3, 7, 2, 3, 4, 7, 8, 9, 2, 3];

            function indexesOf(num) {
                var reduced = arr.reduce(function(acc, val, ind, arr){
                  if(val === num){
                    acc.push(ind);
                  } 
                  return acc;
                }, []);
                return reduced;
            }

indexesOf(2); //[2, 5, 11]
Alireza
  • 100,211
  • 27
  • 269
  • 172
1

AFAIK, there's no Javascript or jQuery function that does this in one step, you have to write a loop.

var indexes = [];
$.each(abc, function(i, val) {
    if (val == "a") {
        indexes.push(i);
    }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

Do it this way :

var abc = ['a','a','b','a','c'];

for (var i=0; i<abc.length; i++) {if(abc[i]=='a') {console.log(i)};}

PG1
  • 1,220
  • 2
  • 12
  • 27
1

If your array size is fixed, then you can find the first occurrence in the array using indexOf(). Use the found index value as starting point in indexOf() to find an other occurrence.

var firstOccurance = [your_array].indexOf(2)
var secondOccurance = [your_array].indexOf(2, firstOccurance + 1)
Vega
  • 27,856
  • 27
  • 95
  • 103
CeamKrier
  • 629
  • 7
  • 15
0

Demo use for loop

 var arr = ['a', 'a', 'b', 'a', 'c'];

var indexA = [];
for (var i = 0; i < arr.length; i++) {

    if ("a" == arr[i]) indexA.push(i)
}
Balachandran
  • 9,567
  • 1
  • 16
  • 26
0

With ES6 syntax you could go with forEach and the ternary operator :

const abc = ['a','a','b','a','c']
let matchingIndexes = []
abc.forEach( (currentItem, index) => {
     currentItem === 'a' ? matchingIndexes.push(index) : null
})
console.log(matchingIndexes) // [0, 1, 3]