1

as answer to an exercise in which I had to create a function that given an array of numbers return the number with most occurrences, and if more than one number had the max number of occurrences return the minor one. This is the implementation I made, but I'm pulling my hair figuring out why it return 10 instead of 9 in the example.

It appears to be evaluating 10 < 9 as true. What's wrong?

function maxOccurencies(arr) {
    var aux = [], max = 0, final = null;
    
    for (var i=0,t=arr.length; i<t; i++) {
        aux[arr[i]] = (aux[arr[i]] || 0) + 1;
        if (aux[arr[i]] > max) max = aux[arr[i]];
    }
    
    for (x in aux) {
        if ( aux[x] == max  && (x < final || final == null)) {
            final = x;
        }
    }    
   
    return final;
}

document.write(maxOccurencies([10,10,10,9,9,9,8,7,4,5,1]));

3 Answers3

1

Putting typeof(x) in your second loop reveals that some of your variables are being cast as type string! Still looking into exactly where this is occurring. You can replace

if ( aux[x] == max  && (x < final || final == null)) {

with

if ( aux[x] == max  && (parseInt(x) < parseInt(final) || final == null)) {

to return the correct value of 9.

Edit:

Very interesting, I was unaware of Javascript's exact handling of arrays in for...in loops. See the following other questions for more information:

JavaScript For-each/For-in loop changing element types

Why is using “for…in” with array iteration such a bad idea?

Also note that you can use arr.forEach(function(element){...}); and the elements are returned with their types intact.

Community
  • 1
  • 1
Jacob See
  • 755
  • 6
  • 17
0

I think the problem is just that the x in aux is not a number so the if statement isn't evaluating correctly. when converted to a number then it returns 9 (below).

(3 == 3 && ("10" < "9" || "9" == null)) evaluates to true

function maxOccurencies(arr) {
    var aux = [], max = 0, final = null;
    
    for (var i=0,t=arr.length; i<t; i++) {
        aux[arr[i]] = (aux[arr[i]] || 0) + 1;
        if (aux[arr[i]] > max) max = aux[arr[i]];
    }
    for (x in aux) {
        if ( aux[x] == max  && (parseInt(x) < final || final == null)) {
            final = parseInt(x);
        }
    }    
   
    return final;
}

document.write(maxOccurencies([10,10,10,9,9,9,8,7,4,5,1]));
mplaza
  • 31
  • 2
0

"I'm pulling my hair figuring out why it return 10 instead of 9 in the example."

That's because in this sort of comparison, 10 is smaller than 9,8,7,6,5,4,3, 2 but a bit grater than 1. :)

This small type correction will fix it:

function maxOccurences(arr) {
    aux = [], max = 0, final = null;

    for (var i=0,t=arr.length; i<t; i++) {
        aux[arr[i]] = (aux[arr[i]] || 0) + 1;
        if (aux[arr[i]] > max) max = aux[arr[i]];
    }

    for (x in aux) {
        if ( aux[x] == max  && (+x < final || final == null)) {
            final = x;
        }
    }    

    return final;
} 
Bekim Bacaj
  • 5,707
  • 2
  • 24
  • 26