16

I wrote this function, which returns -1.

function sayHello() {
  let arrayEdificiosNiveis = [11,10,10];
  var indexMenor = arrayEdificiosNiveis.indexOf(Math.max(arrayEdificiosNiveis));
  console.log(indexMenor);
}
sayHello();

I expected 0, not -1. How do I solve this problem?

3

4 Answers 4

14

You need to spread the array for getting the maximum. Otherwise you get NaN as value (via a stringed array) and this is not in the array (and not searchable).

A spreaded array takes all elements as parameter for the function (spread syntax ...).

In this case it follows this way

Math.max(...[11, 10, 10])

is evaluated as

Math.max(11, 10, 10)

function sayHello() {
  arrayEdificiosNiveis = [11, 10, 10];
  var indexMenor = arrayEdificiosNiveis.indexOf(Math.max(...arrayEdificiosNiveis));
  
  console.log(indexMenor);
}

sayHello();

A single loop solution:

But why not use

v > a[r] ? i : r

(which feels more natural, sort of) instead of

v <= a[r] ? r : i

The problem is the first comparison with the first element at index zero. at this time, r = -1 and the element is a[r] = undefined.

A comparison with undefined and a relational operator of <, <=, > or >= is always false and that would return the wrong index of -1 instead of zero and this result does not change for any other element of the array.

const
    getFirstIndexOfMaxValue = array =>
        array.reduce((r, v, i, a) => v <= a[r] ? r : i, -1);            

console.log(getFirstIndexOfMaxValue([]));
console.log(getFirstIndexOfMaxValue([11]));
console.log(getFirstIndexOfMaxValue([11, 10]));
console.log(getFirstIndexOfMaxValue([11, 10, 10]));
console.log(getFirstIndexOfMaxValue([10, 11, 10]));
console.log(getFirstIndexOfMaxValue([10, 11, 10, 11]));

Sign up to request clarification or add additional context in comments.

3 Comments

This is a bad answer. It needlessly searches the array twice.
@Timmmm, right, this answer was focussed on the use of Math.max. please have a look to the edit, where a single loop returns the index of the first found max value
Definitely better! Unfortunately if you check the link in my answer reduce() is almost as slow as max followed by indexOf. Or at least it was in 2014. Probably worth benchmarking again.
2

You can ask Raymond Chen. It turns out the obvious C-style way is the best. Perhaps unsurprisingly - C style code is easy for Javascript engines to optimise.

function indexOfSmallest(a) {
 var lowest = 0;
 for (var i = 1; i < a.length; i++) {
  if (a[i] < a[lowest]) lowest = i;
 }
 return lowest;
}

Comments

2

The problem in your approach is the complete array you're passing on the function Math.max:

const arrayEdificiosNiveis = [11, 10, 10],
  max = Math.max(...arrayEdificiosNiveis);
  
console.log(arrayEdificiosNiveis.findIndex(elem => elem === max));

If it's not possible to use Spread syntax, you can call the function apply which receives an array as the parameters of function Math.max

function sayHello() {
  const arrayEdificiosNiveis = [11, 10, 10],
    max = Math.max.apply(null, arrayEdificiosNiveis),
    indexMenor = arrayEdificiosNiveis.indexOf(max);
  console.log(indexMenor);
}
sayHello();

4 Comments

@NinaScholz you're right!.. this is a second alternative.
... and how is this different from the answers in the proposed duplicate?
this is returning the index of the min - not the min itself - the former being what this question provides and what I need right now!
This pointlessly searches the array twice.
0
let array=[-2, 4, 3, 2, 1, 7, 6, 10, 8, 9]; //or [1,1,1,1,1,1,1,1,1] 
let result = "";
let fin = "";
let i = 0;
while (i <= array.length)
{
  i++;
 let temp = array[0]; //Assigning the first element of the array
  let temp1 = array[i]; //Assigning the elements through iterating the array
if (temp === temp1){ // If the value of the array is same as [1,1,1,...]
    fin = temp;
    result = temp1;
}
else if (temp > temp1){ // assign minimum value in result variable
  result = temp1;
}
else if(result < temp){ // assing minimum value in fin variable if the first element is minimum
 fin = result; 
}
}
if(fin < result){ // display the result
 console.log(fin); 
}else{            // display the result
console.log(result);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.