Extends the Array.prototype by implementing a groupBy method to generate groupings and nested groups.
// sample data array:
var data = [
{"isActive":false,"age":21,"eyeColor":"brown","name":{"first":"Joy","last":"Bryant"}, "gender":"female"},
{"isActive":true,"age":30,"eyeColor":"green","name":{"first":"Mcmahon","last":"House"}, "gender":"male"},
{"isActive":true,"age":21,"eyeColor":"brown","name":{"first":"Humphrey","last":"Reilly"}, "gender":"female"},
{"isActive":false,"age":21,"eyeColor":"blue","name":{"first":"Lacy","last":"Carrillo"}, "gender":"female"},
{"isActive":false,"age":26,"eyeColor":"green","name":{"first":"Beard","last":"Merrill"}, "gender":"male"},
{"isActive":true,"age":35,"eyeColor":"brown","name":{"first":"Drake","last":"Bean"}, "gender":"male"},
{"isActive":true,"age":30,"eyeColor":"brown","name":{"first":"Kemp","last":"Griffith"}, "gender":"male"}
];
// simple grouping by gender:
var genderGroups = data.groupBy(function(user){ return user.gender });
// output:
[
{"key":"female",
"items":[
{"isActive":false,"age":21,"eyeColor":"brown","name":{"first":"Joy","last":"Bryant"},"gender":"female"},
{"isActive":true,"age":21,"eyeColor":"brown","name":{"first":"Humphrey","last":"Reilly"},"gender":"female"},
{"isActive":false,"age":21,"eyeColor":"blue","name":{"first":"Lacy","last":"Carrillo"},"gender":"female"}
]},
{"key":"male",
"items":[
{"isActive":true,"age":30,"eyeColor":"green","name":{"first":"Mcmahon","last":"House"},"gender":"male"},
{"isActive":false,"age":26,"eyeColor":"green","name":{"first":"Beard","last":"Merrill"},"gender":"male"},
{"isActive":true,"age":35,"eyeColor":"brown","name":{"first":"Drake","last":"Bean"},"gender":"male"},
{"isActive":true,"age":30,"eyeColor":"brown","name":{"first":"Kemp","last":"Griffith"},"gender":"male"}
]}
];
In general, groups can be unlimitedly nested:
// nested grouping, first by gender, than by eye color:
var genderGroups = data.groupBy(function(user){ return user.gender });
var nestedGroups = genderGroups.groupBy(function(user){ return user.eyeColor; });
// output:
[
{"key":"female",
"items":[
{
"key":"brown",
"items":[
{"isActive":false,"age":21,"eyeColor":"brown","name":{"first":"Joy","last":"Bryant"},"gender":"female"},
{"isActive":true,"age":21,"eyeColor":"brown","name":{"first":"Humphrey","last":"Reilly"},"gender":"female"}
]
},
{
"key":"blue",
"items":[
{"isActive":false,"age":21,"eyeColor":"blue","name":{"first":"Lacy","last":"Carrillo"},"gender":"female"}
]
}
]},
{"key":"male",
"items":[
{
"key":"brown",
"items":[
{"isActive":true,"age":35,"eyeColor":"brown","name":{"first":"Drake","last":"Bean"},"gender":"male"},
{"isActive":true,"age":30,"eyeColor":"brown","name":{"first":"Kemp","last":"Griffith"},"gender":"male"}
]
},
{
"key":"green",
"items":[
{"isActive":true,"age":30,"eyeColor":"green","name":{"first":"Mcmahon","last":"House"},"gender":"male"},
{"isActive":false,"age":26,"eyeColor":"green","name":{"first":"Beard","last":"Merrill"},"gender":"male"}
]
}
]}
];
You also can chain the groupBy calls:
var nestedGroups = data
.groupBy(function(user){ return user.gender; })
.groupBy(function(user){ return user.eyeColor; });
Array.groupBy can also be called by providing a property path instead of a function:
var keyProperty = 'name.first'
var firstNameGroups = data.groupBy(keyProperty);
groupBy is able to resolve any type of property path:
var key = 'prop.foo.baz.arr[1].func.0.val' // valid
data.isGrouped // undefined
genderGroups.isGrouped // true
// first group's items:
genderGroups[0].items.isGrouped // false
nestedGroups.isGrouped // true
// first group's items:
nestedGroups[0].items.isGrouped // true