DEV Community

Discussion on: Are one-liners always the best solutions?

Collapse
 
aminmansuri profile image
hidden_dude • Edited

The one liner solution here would be to use reduce.
Or map and reduce.

It's important to use the right tool for the job.

For example:

  1. Map the array to the tuple: (num, occ). Ie. number and occurrences, where it would be mapped to 1 initially.
    For example:
    [1,2,3,2,3] => [(1,1),(2,1),(3,1),(2,1),(3,1)]

  2. Reduce to find the max and sum occurrences:
    [(1,1),(2,1),(3,1),(2,1),(3,1)] => (3,2)

Then you basically have your solution that is O(N) so it's faster than solutions based on sort.

Reduce is what you need to convert a list of values into a single solution. But sometimes you need to convert the list into something else to be able to reduce it.

The code would be something like:

arr.map( n => [n,1]).reduce( (result, tuple) =>  
     (result[0] > tuple[0]) ? result :
          (result[0] == tuple[0]) ? [result[0], result[1]+1] :
               tuple)
Enter fullscreen mode Exit fullscreen mode

The lambda can probably be written clearer.

Collapse
 
kahawaiikailana profile image
Kailana Kahawaii

Awesome! I love seeing solutions like these.

Collapse
 
aminmansuri profile image
hidden_dude • Edited

In some languages map/reduce are lazy so it's super efficient to do this (ie. it only goes through the array once). Not sure about Javascript though.

Still, going through the array twice is still more efficient than sorting. Though it's a pity the array has to be copied (in Java or .Net the array wouldn't need to be copied for example, so in theory it's as efficient as the raw for loop, but more readable).

Collapse
 
aminmansuri profile image
hidden_dude

If you hate the double loop you can avoid the map like this:


arr.reduce( (result, num) =>  
     (result[0] > num) ? result :
          (result[0] ==num) ? [result[0], result[1]+1] :
               [num,1],  (arr[0],0))
Enter fullscreen mode Exit fullscreen mode

This does it all in one pass.