How do I get the highest value in an array with JavaScript?

1

Hello, I created a function that should iterate through an array and return the highest value. It even works in some cases, but depending on the order of the array it returns the wrong value.

I know that I can use the max method of the Math object, but wanted to know what is wrong with the logic of this function?

function encontraMaior(array) {
    //Variavel que armazena o maior valor encontrado
    var maior;

    //Se o array for vazio lança um erro
    if(array.length < 1) {
       throw new Error('Empty array');
    }

    for (let i = 0; i < array.length; i++) {
        let a, b;

        a = array[i];
        b = array[i+1];

        //Caso o array tenha apenas um numero
        if (!b) {
            b = 0;
        }

        /*Compara a variavel "a" com "b" e atribui o maior valor
        a variavel "maior"*/

        if (a > b) {
            maior = a;
        } 

        else if (b > a) {
            maior = b;
        }

        else if(a === b) {
            maior = a;
        }
    }

    return maior;
}
    
asked by anonymous 19.03.2018 / 16:14

4 answers

3

The problem is with the logic itself that you are using. You can not build the largest just based on the two elements you analyze, because those that have been parsed back will be disregarded.

I put your code with console.log through the middle to see the comparisons and assignments it does:

function encontraMaior(array) {
    var maior;
    if(array.length < 1) {
       throw new Error('Empty array');
    }

    for (let i = 0; i < array.length; i++) {
        let a, b;
        a = array[i];
        b = array[i+1];

        if (!b) {
            b = 0;
        }

        console.log('A comparar ${a} com ${b}');

        if (a > b) {
            maior = a;
        } 
        else if (b > a) {
            maior = b;
        }
        else if(a === b) {
            maior = a;
        } 
        console.log('O maior é agora ${maior}');
    }
    return maior;
}

let arr = [10,3,1,6,7,2];
console.log(encontraMaior(arr));

Notice that for the array:

[10,3,1,6,7,2]
  • Compare 10 with 3 to find that the largest is 10
  • But then it compares 3 to 1 and says that the largest is 3 .

This is because in your code only the two current numbers are of interest, which means that only the last comparison will prevail. However when you are in the last element when doing:

b = array[i+1];

i+1 will already be out of valid positions and b will have undefined . So with if that follows:

if (!b) { 
    b = 0;
}

As b has undefined enters if and gets 0 causing a to be greater (unless it is negative). You can see this in the last comparison that is shown in the snippet , the "A comparar 2 com 0" . In conclusion, its function encontraMaior always returns the last element, which may coincidentally be the largest.

There is no way to correct without even changing logic. Since you want to implement by hand make it normal that it is much simpler:

function encontraMaior(array) {
    if(array.length < 1) {
       throw new Error('Empty array');
    }
    var maior = array[0]; //mais alto iniciado como o primeiro elemento
    
    for (let i = 1; i < array.length; ++i){
    //           ^--- Começa no segundo pois o primeiro já foi considerado

        //se o valor que tem no momento é maior que o mais alto
        if (array[i] > maior){ 
            maior = array[i]; //atualiza o mais alto
        }
    }
    
    return maior;
}

let arr = [10,3,1,6,7,2];
console.log(encontraMaior(arr));

In real situations do not reinvent the wheel and use the functions that already exist for this, in this case the Math.max you mentioned:

function encontraMaior(array){
    return Math.max(...array);
}

let arr = [10,3,1,6,7,2];
console.log(encontraMaior(arr));

In this last example I used the spread operator to expand the elements for the max function.

    
19.03.2018 / 19:45
0

Because your logic has several points of failure. Basically in your script you try to compare the current item with the next.

 a = array[i];
 b = array[i+1];

Since in the assignment of b , if the pointer is already in the last element of the array, you are extrapolating the size of it and trying to access an element that does not exist.

Soon after you make the wrong comparisons to store the highest value.

    if (a > b) {
        maior = a;
    } 

    else if (b > a) {
        maior = b;
    }

    else if(a === b) {
        maior = a;
    }

In addition to being redundant and irrelevant, you are currently not checking whether the value you are assigning is greater than already stored in the maior variable and is always substituting a or b , which are the two values which are being compared in this iteration.

Below is an example of the most common way to solve the problem.

function encontraMaior(array) {    
    //Se o array for vazio lança um erro
    if(array.length < 1) {
       throw new Error('Empty array');
    }

    //Recebe o primeiro elemento do array
    var maior = array[0];

    //Faz o loop a partir do segundo elemento para fazer as comparações
    for (let i = 1; i < array.length; i++) {
        var atual = array[i];
        if( atual > maior)
         maior = atual;
    }

    return maior;
}
    
19.03.2018 / 16:48
0

There are some logic errors in your function (I've used comments in your own code to highlight them):

function encontraMaior(array) {

var maior;


if(array.length < 1) {
   throw new Error('Empty array');
}

//Você pode percorrer incrementando os índices em 2, pois já está comparando
// dois índices a cada iteração (a e b)
for (let i = 0; i < array.length; i = i + 2) {
    let a, b;

    a = array[i];

   //Checa se a posição (i+1) existe e considera b como 0 caso negativo
    if (i + 1 > array.length - 1) {
        b = 0;
    }
    else {
        b = array[i+1];
    }

    //Conferir se maior não foi inicializado ainda, para atribuir um valor
    // inicial que será comparado posteriormente (inclusive dentro do mesmo
    // laço que inicializou, possibilitando que b seja considerado o maior
    if(maior == null){
       maior = a;
    }

    //Deve comparar as variáveis a e b também com o valor de maior, pois no
    // no algoritmo original o valor de maior é perdido em cada iteração
    if (a > b && a > maior) {
        maior = a;
    } 

    else if (b > a && b > maior) {
        maior = b;
    }

    else if(a === b && a > maior) {
        maior = a;
    }
}    

return maior;
}
    
19.03.2018 / 18:52
-1

The Math.max function already returns the largest of two:

Math.max(10, 20);   //  20
Math.max(-10, -20); // -10
Math.max(-10, 20);  //  20

With reduce you could use an array:

var arr = [1, 2, 3];
var max = arr.reduce(function(a, b) {
  return Math.max(a, b);
});
    
19.03.2018 / 21:31