How to find index of not only the first element that meets the condition but of every elements of the array, using '.findIndex()'?

Hi! I want to iterate over all element of an array and get the index of each element that fits the condition stated using .findIndex().
example…

const animals = [
  "hippo",
  "tiger",
  "lion",
  "seal",
  "cheetah",
  "monkey",
  "salamander",
  "elephant",
];

const startsWithS = animals.findIndex((animal) => {
  return animal[0] === 's';
});
console.log(startsWithS); //prints 3... index of 'seal'

but I want to get not only the index of the first element that starts with ‘s’, I also want the index of ‘salamander’. is it possible using .findIndex() method? if so how would that be done? If not what are the ways to go about it?

Sadly, I don’t think there’s a way of manipulating findIndex, short of something more janky, to get the index of every element which passes a condition.

Here’s one way you could do it:

let startsWithS = []
animals.forEach((animal, index) => { 
    if (animal[0] === 's') { 
        startsWithS.push(index) 
    }
}

The code above iterates through animals and pushes the index of each element that starts with an ‘s’ to the startsWithS array. Later, you could return or log startsWithS.

Another method using .map and .filter:

const startsWithS = animals
                       .map((animal, index) =>  index)
                       .filter(index => animals[index][0] === 's')

Here we create an array from animals using .map with only the indexes of each animal from the original array, then, using .filter on that mapped array, we filter out the indexes which correspond to an animal in animals that start with ‘s’.

This last one uses .reduce:

const startsWithS = animals.reduce((acc, animal, index) => {
  if (animal[0] === 's') {
    acc.push(index);
  }
  return acc;
}, []);

Basically, for every current element (animal), if its first letter is ‘s’, we push its index to the accumulating array we initialize as the first parameter (acc). Then, we return the accumulated array.

As for which method to use, choose the one that makes the most sense to you and which you suspect would make the most sense for anyone who would be likely to see and edit your code.

2 Likes

I challenged myself afterwards to create a one-liner, so here ya go:

const startsWithS = animals.reduce((acc, animal, index) => animal[0] === 's' ? [...acc, index] : acc, []);
1 Like