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 Answers 3

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.

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

1 Comment

Yes, for x in y gives values for x that are really keys instead of numbers. You can use them for y[x], but not for other calculations without converting their type.
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]));

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.