Hacker News new | ask | show | jobs
by ryanthejuggler 4089 days ago
The "official" way to do this is map, then reduce. The way reduce is meant to be used exactly matches this implementation.

Consider that you have a large quantity of numbers that you want to get the min, max, mean for. If you write something like the following:

    function minMaxMean(list) {
      return list.reduce(function(lastState, n) {
        var min = lastState.min,
            max = lastState.max,
            sum = lastState.sum,
            count = lastState.count;
        if(n < min) min = n;
        if(n > max) max = n;
        sum += n;
        count += 1;
        return {
          min: min,
          max: max,
          sum: sum,
          count: count
        }
      }, {min: Infinity, max: -Infinity, sum: 0, count: 0});
    }
...then you're assuming that the reduce function will run once, over a single list of numbers, in order from left to right. However, if you implement it as the following:

    function minMaxMean(list) {
      return list.map(function(n){
        return {
          min: n,
          max: n,
          sum: n,
          count: 1
        }
      }).reduce(function(a, b) {
        return {
          min: (a.min < b.min ? a.min : b.min),
          max: (a.max > b.max ? a.max : b.max),
          sum: a.sum + b.sum,
          count: a.count + b.count
        }
      });
    }
...then you can distribute this out across multiple threads/machines/etc, update it when new data comes in, reduce in any order.
1 comments

There are many cases of elegantly using reduce() with a different return type than the list's item type.

Here is a JS function which computes the combined length of all strings in a list:

    stringsLen = (strings) => strings.reduce((acc, item) => acc += item.length, 0);
    
    stringsLen(['hello', 'world'])  //> 10
Sure, you can argue that this works, but it misses the point.

    stringsLen = (strings) => strings.map(s => s.length).reduce((acc, n) => acc += n, 0);
    
     stringsLen(['hello', 'world'])