Underscore.js groupBy multiple values Underscore.js groupBy multiple values arrays arrays

Underscore.js groupBy multiple values


A simple recursive implementation:

_.mixin({  /*   * @mixin   *   * Splits a collection into sets, grouped by the result of running each value   * through iteratee. If iteratee is a string instead of a function, groups by   * the property named by iteratee on each of the values.   *   * @param {array|object} list - The collection to iterate over.   * @param {(string|function)[]} values - The iteratees to transform keys.   * @param {object=} context - The values are bound to the context object.   *    * @returns {Object} - Returns the composed aggregate object.   */  groupByMulti: function(list, values, context) {    if (!values.length) {      return list;    }    var byFirst = _.groupBy(list, values[0], context),        rest    = values.slice(1);    for (var prop in byFirst) {      byFirst[prop] = _.groupByMulti(byFirst[prop], rest, context);    }    return byFirst;  }});

Demo in your jsfiddle


I think @Bergi's answer can be streamlined a bit by utilizing Lo-Dash's mapValues (for mapping functions over object values). It allows us to group the entries in an array by multiple keys in a nested fashion:

_ = require('lodash');var _.nest = function (collection, keys) {  if (!keys.length) {    return collection;  }  else {    return _(collection).groupBy(keys[0]).mapValues(function(values) {       return nest(values, keys.slice(1));    }).value();  }};

I renamed the method to nest because it ends up serving much the same role served by D3's nest operator. See this gist for details and this fiddle for demonstrated usage with your example.


How about this rather simple hack?

console.log(_.groupBy(getProperties(), function(record){    return (record.size+record.category);}));