How to get the highest value in an array with Javascript?

Asked

Viewed 2,906 times

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 I can use the max method of the Math object, but I wanted to know what is wrong in 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;
}
  • Do the table test in your role and you will understand what is wrong.

  • to begin, this code will give error in the last item of the array: b = array[i+1]. You are trying to read the next element, this will give error, you just need to look at the current element (index i)

  • @Ricardopunctual Will not give error in the last element but return undefined in relation to b = array[i+1] which will be caught by if (!b) {. The problem really lies in the logic itself.

  • @Isac when he said error was not in the sense of Exception, but will generate a comparison error that can invalidate if the penultimate number is the largest, because for example any number, 10. Compare 10 < undefined or 10 > undefined or 10 === undefined all return false invalidating the logic

  • I understand your question, but if you give a Sort array in your array before starting the comparisons, I think it will be more right.

4 answers

3


The problem lies in the logic you are using. You can not build the largest only based on the two elements you analyze, as those that have been analyzed backwards will be disregarded.

I put your code with some console.log through the medium in order to see the comparisons and assignments he makes:

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));

Note that for the array:

[10,3,1,6,7,2]
  • Compares the 10 with 3 to discover that the greatest is the 10
  • But then immediately compares the 3 with the 1 and says the greatest is 3.

This is because in your code only the two current numbers matter, which means that only the last comparison will prevail. Yet when you’re in the last element of doing:

b = array[i+1];

i+1 will already be out of the valid positions and b will stay with undefined. As with the if next:

if (!b) { 
    b = 0;
}

Like b has undefined gets into the if and gets 0 causing the a is larger (unless negative). You can see this in the last comparison shown in snippet previous, the "A comparar 2 com 0". In conclusion, your role encontraMaior always returns the last element, which may coincidentally be the largest.

There is no way to fix without even changing the logic. Since you want to implement by hand do the normal which 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 re-invent the wheel and use the functions that already exist for this purpose, in this case the Math.max who 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 to the function max.

  • Sensational explanation, thank you very much, I understood why logic is wrong. The fact that the function always compares the current and the previous one and returns the larger one, it always made the comparison between these two numbers, not the whole array. And thank you for the day to not "reinvent the wheel".

0

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

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

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

Right after you make mistaken 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 redundant and irrelevant, at no time are you checking whether the value you are assigning is higher than already stored in the variable maior and is always replacing by a or b, which are the two values that 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;
}
  • @Andersoncarloswoss lacked some point?

  • Thank you very much, I left the question here this morning and went to see now, before that I broke my head a little bit and saw that the biggest problem was that I was not storing the greatest value, I was just comparing between a and b as you said. Which resulted in two options, one using the max function of the Math class, and the other a little longer improving my logic. But the above example greatly simplifies things, thank you very much.

0

There are some logic errors in their function (I used comments in their 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;
}

-1

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

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

With reduce vc could use an array:

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.