One of my daily code challenges this week was to return the number of occurrences of the max value of an array. At first I just tried the "brute force" iteration approach with a dictionary to keep track of the count:
const ar = [3,2,1,3] // there are 2 3's so 2 should be my result
const dict = {}
for (let i=0; i<ar.length; i++){
if (dict[ar[i]]){
dict[ar[i]]++
} else {
dict[ar[i]]=1
}
}
// console.log(Object.keys(dict).length)
return (Object.values(dict).sort()[Object.keys(dict).length-1])
... which did work but I always like to shoot for a "one-line" solution.
So, I took my iteration and started thinking through the built in prototype.Array functions in JavaScript. I decided to use "filter()" because it will return a sub-set of the original array. Then I can use "length" to get the count of the elements that match the filter. Seems easy enough:
ar.filter(el => el == 3).length // returns 2
My "3" comparison value is just psuedocode for now, only because I already know the max value. Now I have to find the max value so I can make this a dynamic function. I can use "Math.max()" to determine the max value of the array:
Math.max(...ar) // returns 3
// using the spread operator "..." is shorthand for using "apply". The "apply" method could also be used:
Math.max.apply(null, ar)
So now I can just replace my psuedocode value with the function to find the max of the array:
ar.filter(el => el == Math.max(...ar)).length // returns 2
...which does work but since this is a code challenge, the solution times out and fails the test cases (if you do code challenges, you know what this means).
I examined what was happening and noticed that even if a function is nested within another function - on one line or otherwise - it still is a nested function. For every element of the ar filter step, it was checking to find the max value of the array. I'm pretty sure this would be O(n^2). But if I create a variable (maxVal) and assign the max value (Math.max(...ar)) OUTSIDE of the filter function, then the timeout errors go away and all test cases pass:
const maxVal = Math.max(...ar)
return (ar.filter(el => el == maxVal).length)
So, not exactly a one line solution but much leaner and cleaner than the "brute force" method where I started. And a valuable lesson, for sure!
Top comments (0)