JavaScript indexOf method with multiple values

44,411

Solution 1

Just make it a for loop to check each array element.

var array = ["test234", "test9495", "test234", "test93992", "test234"];

for (i=0;i<array.length;i++) {
  if (array[i] == "test234") {
    document.write(i + "<br>");
  }
}

Solution 2

This kind of function doesn't exist built in, but it would be pretty easy to make it yourself. Thankfully, indexOf can also accept a starting index as the second parameter.

function indexOfAll(array, searchItem) {
  var i = array.indexOf(searchItem),
      indexes = [];
  while (i !== -1) {
    indexes.push(i);
    i = array.indexOf(searchItem, ++i);
  }
  return indexes;
}

var array = ["test234", "test9495", "test234", "test93992", "test234"];
document.write(JSON.stringify(indexOfAll(array, "test234")));

Solution 3

You can use reduce:

const indexesOf = (arr, item) => 
  arr.reduce(
    (acc, v, i) => (v === item && acc.push(i), acc),
  []);

So:

const array = ["test234", "test9495", "test234", "test93992", "test234"];
console.log(indexesOf(array, "test234")); // [0, 2, 4]

An alternative approach could be having an iterator:

function* finder(array, item) {
  let index = -1;
  while ((index = array.indexOf(item, index + 1)) > -1) {
    yield index;
  }
  return -1;
}

That's give you the flexibility to have the search in a lazy way, you can do it only when you need it:

let findTest234 = finder(array, "test234");

console.log(findTest234.next()) // {value: 0, done: false}
console.log(findTest234.next()) // {value: 2, done: false}
console.log(findTest234.next()) // {value: 4, done: false}    
console.log(findTest234.next()) // {value: -1, done: true}

Of course, you can always use it in loops (since it's an iterator):

let indexes = finder(array, "test234");

for (let index of indexes) {
   console.log(index);
}

And consume the iterator immediately to generate arrays:

let indexes = [...finder(array, "test234")];
console.log(indexes); // [0, 2, 4]

Hope it helps.

Solution 4

You can use the fromIndex of Array#indexOf.

fromIndex

The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array. Note: if the provided index is negative, the array is still searched from front to back. If the calculated index is less than 0, then the whole array will be searched. Default: 0 (entire array is searched).

~ is a bitwise not operator.

It is perfect for use with indexOf(), because indexOf returns if found the index 0 ... n and if not -1:

value  ~value   boolean
-1  =>   0  =>  false
 0  =>  -1  =>  true
 1  =>  -2  =>  true
 2  =>  -3  =>  true
 and so on 

var array = ["test234", "test9495", "test234", "test93992", "test234"],
    result = [],
    pos = array.indexOf('test234');

while (~pos) {
    result.push(pos);
    pos = array.indexOf('test234', pos + 1); // use old position incremented
} //                               ^^^^^^^

document.write('<pre> ' + JSON.stringify(result, 0, 4) + '</pre>');
Share:
44,411
Jason Aller
Author by

Jason Aller

I've debugged a lot of code over the years, most of it my own. First learn to code to the standard, then learn when to break the rules. Every language has a beauty, embrace it. There are tools that will help along this path... finding the right editor or IDE is important for any language, for JavaScript I've found the JSLint -&gt; JSHint -&gt; ESLint evolution, followed by Yeoman's Grunt to be really instructive and useful.

Updated on December 21, 2021

Comments

  • Jason Aller
    Jason Aller over 2 years

    I have an array which contains multiple same values

    ["test234", "test9495", "test234", "test93992", "test234"]
    

    Here I want to get the index of every test234 in the array

    For that I've tried Array.prototype.indexOf() method. But It only returns me 0 but I want it to return me [0, 2, 4].

    How can I do that?

    var array = ["test234", "test9495", "test234", "test93992", "test234"];
    document.write(array.indexOf("test234"));

  • Admin
    Admin about 8 years
    Can you make it as a prototype?
  • 4castle
    4castle about 8 years
    I know exactly what it does and how it works. I'm just saying it's confusing in general. I prefer to code exactly what I mean instead of using strange operators. When it comes down to it, our code is almost identical.
  • 4castle
    4castle about 8 years
    @MrZ If you mean adding it to Array.prototype, then the answer is yes, but that is bad practice and it has some unexpected effects. You would have to initialize every array using new Array() instead of [] for it to work. You're better off just making utility functions.
  • 4castle
    4castle about 8 years
    You really should be using === instead of == for this to be a fool proof answer. See this
  • JoeL
    JoeL about 8 years
    @4castle I'll admit I don't have any experience with the triple = so while I read the link, it's still not perfectly clear to me what exact situations I should use it.
  • Miguel
    Miguel over 6 years
    @JoeL The === checks for type , so "1" and 1 and not the same when using === but when using == they are, because they are compared using a string or a numeric. So, == its more permissive because uses a loosely comparison.
  • Greggory Wiley
    Greggory Wiley about 3 years
    Really like this code and reducer functions, could you add a note about what each variable represents, wondering exactly what to use for arr, item, acc, v, i.
  • ZER0
    ZER0 about 3 years
    Thanks! If you're referring to (acc, v, i), they're just the accumulator, the value, and the index as described in the reduce documentation I linked. Or did you mean something else?