Fred J.
Fred J.

Reputation: 6049

javascript, get indices of given value in array

This JavaScript code tries to get the indices of a given value 5 in a new array. Any idea how to do it in an elegant way. I cold use for loop but I was hoping to use map or reduce. thx.

console.log( [1, 2, 3, 5, 6, 5].map((y, i) => {
  if (y === 5) return i
}))
// gives --> [undefined, undefined, undefined, 3, undefined, 5]
// expected [3,5]

Upvotes: 1

Views: 78

Answers (6)

rugg
rugg

Reputation: 551

console.log( [1, 2, 3, 5, 6, 5].map((y, i) => {
  if (y === 5) return i
}).filter((x) => {return /\d/.test(x);}));

Upvotes: 1

samanime
samanime

Reputation: 26625

You can either use map() or reduce().

reduce() will be able to do it in a single loop:

[1,2,3,4,5].reduce((result, num, index) => result.concat(num === 5 ? index : []), []);

Using concat() instead of push() is a tiny bit slower, but cleaner, and in reasonably small sets, the difference will be negligible.

map() will need filter() to remove extras:

[1,2,3,4,5].map((num, index) => num === 5 && index)
    .filter(e => e !== false);

.filter(Boolean) is a clean, short-hand way of casting whatever value to a Boolean, which filter will then use to determine what it needs to do. num === 5 && index will be either false or the index. Another clean way to go through.

Upvotes: 2

Graham
Graham

Reputation: 7802

You could run a map to test the value and write either a null (no match) or the position (match) then a filter to remove the nulls.

The map would look like this:

map( (value, index) => {
  return value === 5 ? index : null;
})

Then you'd filter it like this:

filter( (value) => {
  return value != null;
})

Upvotes: 1

Dai
Dai

Reputation: 155708

Unfortunately map and reduce are not lazily-evaluated in JavaScript (i.e. they're not generators/iterators), but if you don't mind the double array allocation, you can do this:

var indices = [ 1, 2, 3, 5, 6, 5 ]
    .map( ( e, i ) => e == 5 ? i : -1 )
    .filter( e => e > -1 );

// indicies == [3,5]

Another approach, that's cheaper:

var indices = [];
[ 1, 2, 3, 5, 6, 5 ].forEach( (e, i) => e == 5 ? indices.push( i ) : null );

This takes advantage of the fact you can use a void expression inside the ?: ternary operator.

Upvotes: 2

Yashwardhan Pauranik
Yashwardhan Pauranik

Reputation: 5566

You can use reduce operator on your array as:

 [1,2,3,5,6,5].reduce(function(a, e, i) {
        if (e === 5)
            a.push(i);
        return a;
    }, []);

Upvotes: 1

Bill Criswell
Bill Criswell

Reputation: 32941

You can use reduce. The third argument of the callback is the index.

[1, 2, 3, 5, 6, 5].reduce((indexes, n, index) => {
  if (n === 5) indexes.push(index)
  return indexes
}, [])

Upvotes: 2

Related Questions