Skip to content

Commit

Permalink
add array/groupBy. closes #190
Browse files Browse the repository at this point in the history
closes #191
  • Loading branch information
gaye authored and millermedeiros committed Aug 6, 2014
1 parent 826bd67 commit 49a389c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
15 changes: 15 additions & 0 deletions doc/array.md
Expand Up @@ -339,6 +339,21 @@ more info at [MDN Array#forEach](https://developer.mozilla.org/en/JavaScript/Ref



## groupBy(arr, [categorize=identity], [thisObj]):Object

Groups array elements by the `key` returned from the `categorize` function.

It will use the [function/identity](function.html#identity) as the default
`categorize` function.

```js
var items = ['lorem', 'ipsum', 'foo', 'bar', 'baz'];
groupBy(items, function(val) { return val.length });
// > {'3': ['foo', 'bar', 'baz'], '5': ['lorem', 'ipsum']}
```



## indexOf(arr, item, [fromIndex]):Number

Crossbrowser `Array.indexOf()`.
Expand Down
32 changes: 32 additions & 0 deletions src/array/groupBy.js
@@ -0,0 +1,32 @@
define([
'../array/forEach',
'../function/identity',
'../function/makeIterator_'
], function(forEach, identity, makeIterator) {

/**
* Bucket the array values.
*/
function groupBy(arr, categorize, thisObj) {
if (categorize) {
categorize = makeIterator(categorize, thisObj);
} else {
// Default to identity function.
categorize = identity;
}

var buckets = {};
forEach(arr, function(element) {
var bucket = categorize(element);
if (!(bucket in buckets)) {
buckets[bucket] = [];
}

buckets[bucket].push(element);
});

return buckets;
}

return groupBy;
});
41 changes: 41 additions & 0 deletions tests/spec/array/spec-groupBy.js
@@ -0,0 +1,41 @@
define(['mout/array/groupBy'], function(groupBy) {

describe('array/groupBy', function() {
it('should bucket appropriately', function() {
function floor(num) {
return Math.floor(num);
}

// Test case borrowed from lodash.
expect(groupBy([4.2, 6.1, 6.4], floor)).toEqual({
'4': [4.2],
'6': [6.1, 6.4]
});
});

it('should accept thisArg', function() {
var x = { '1': 'left', '2': 'left', '3': 'left', '4': 'right', '5': 'left' };

expect(
groupBy([1, 2, 3, 4, 5], function(key) {
return this[key];
}, x)
)
.toEqual({ 'left': [1, 2, 3, 5], 'right': [4] });
});

it('should default to identity function', function() {
expect(
groupBy([1, 2, 2, 1, 1])
)
.toEqual({ '1': [1, 1, 1], '2': [2, 2] });
});

it('should categorize by property', function() {
expect(
groupBy(['green', 'eggs', 'and', 'ham'], 'length')
)
.toEqual({ '3': ['and', 'ham'], '4': ['eggs'], '5': ['green'] });
});
});
});
1 change: 1 addition & 0 deletions tests/spec/spec-array.js
Expand Up @@ -15,6 +15,7 @@ define([
'./array/spec-findLastIndex',
'./array/spec-flatten',
'./array/spec-forEach',
'./array/spec-groupBy',
'./array/spec-indexOf',
'./array/spec-insert',
'./array/spec-intersection',
Expand Down

0 comments on commit 49a389c

Please sign in to comment.