Pablinx
Pablinx

Reputation: 9

indexOf on Javascript not working as expected on Array

I want to iterate through an Array to find the index of the highest numbers on it, then write those index numbers on another new Array.

I came up with this code:

let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44];
let highestScore = Math.max(...scores);
let topScores = [];


for (score of scores) {
    if (score == highestScore) {
        topScores.push(scores.indexOf(score));
    }
}
console.log(topScores);

Then the result that the console shows is:

 topScores = [11, 11] 

...when I expected:

 topScores = [11, 18] 

as those are the positions where the highest numbers (both 69) are on the scores array.

Can someone explain to me what's happening? I searched but I can't come up with the issue. Thank you very much.

Upvotes: 0

Views: 116

Answers (5)

Anilal
Anilal

Reputation: 134

scores.indexOf(score) always returns the first position of score in the scores.

Use following code if you need the index.

for (let i = 0; i < scores.length; i ++) {
    let score = scores[i];
    if (score == highestScore) {
        topScores.push(i);
    }
}
console.log(topScores);

Upvotes: 0

Fraction
Fraction

Reputation: 12954

As mentioned by Fritz Array.indexOf(x) always returns the first position of x in the array. The first 69 is at index 11.

You can use Array.forEach() instead of for...of:

let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44];
let highestScore = Math.max(...scores);
let topScores = [];


scores.forEach((score, index) => {
    if (score == highestScore) {
        topScores.push(index);
    }
})

console.log(topScores);

Upvotes: 1

codebarz
codebarz

Reputation: 327

the .indexOf() returns only the index of the first occurrence of the particular ignore the other indexes so in this case, indexOf won't work. Just loop through and push the index of the value equal to the maximum number to a new array

let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44];

let noReplica = Math.max(...scores)
let ret = [];
for (let i = 0, length = scores.length; i < length; i++) {
    if (scores[i] === noReplica) {
        ret.push(i)
    }
}

console.log(ret)

Upvotes: 0

connexo
connexo

Reputation: 56770

As others have already mentioned, both indexOf and findIndex always return the index of the first match. But there is no need for using either because you can access the current index in for..of like this:

for (const [index, score] of scores.entries())

which allows you to simply do

topScores.push(index);

let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44];
let highestScore = Math.max(...scores);
let topScores = [];


for (const [index, score] of scores.entries()) {
    if (score == highestScore) {
        topScores.push(index);
    }
}
console.log(topScores);

Upvotes: 0

Maheer Ali
Maheer Ali

Reputation: 36564

This is beacause indexOf always return the first index at which element exist in array. You can use reduce()

let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44];
let highestScore = Math.max(...scores);
let res = scores.reduce((ac,a,i) => (a === highestScore && ac.push(i),ac),[])

console.log(res)

Upvotes: 0

Related Questions