diff --git a/index.html b/index.html index 685706fee..d83ed3796 100644 --- a/index.html +++ b/index.html @@ -141,7 +141,7 @@
_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); }); => [5, 4, 6, 3, 1, 2] ++ +
+ groupBy_.groupBy(list, iterator)
+
+ Splits a collection into sets, grouped by the result of running each
+ value through iterator.
+
+_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); }); +=> {1: [1.3], 2: [2.1, 2.4]}
diff --git a/test/collections.js b/test/collections.js index ff365f8ea..e1dc5ebfc 100644 --- a/test/collections.js +++ b/test/collections.js @@ -185,6 +185,12 @@ $(document).ready(function() { people = _.sortBy(people, function(person){ return person.age; }); equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); }); + + test('collections: groupBy', function() { + var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); + equals(_.keys(parity).join(', '), '0, 1', 'created a group for each value'); + equals(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); + }) test('collections: sortedIndex', function() { var numbers = [10, 20, 30, 40, 50], num = 35; diff --git a/underscore.js b/underscore.js index eaba008c4..468c06a9e 100644 --- a/underscore.js +++ b/underscore.js @@ -250,6 +250,21 @@ return a < b ? -1 : a > b ? 1 : 0; }), 'value'); }; + + // Groups the object's values by a criterion produced by an iterator + _.groupBy = function(obj, iterator) { + var result = {}; + each(obj, function(value) { + var key = iterator(value); + if (result.hasOwnProperty(key)) { + result[key].push(value); + } + else { + result[key] = [value]; + } + }); + return result; + } // Use a comparator function to figure out at what index an object should // be inserted so as to maintain order. Uses binary search.