Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

break array of objects into separate arrays based on a property

Say I have an array like this:

var arr = [
    {type:"orange", title:"First"},
    {type:"orange", title:"Second"},
    {type:"banana", title:"Third"},
    {type:"banana", title:"Fourth"}
];

and I want this to be split up into arrays that have objects which have same type so:

[{type:"orange", title:"First"},
{type:"orange", title:"Second"}]

[{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}]

But I want to do this generically so not having an if statement that specifies orange or banana

// not like this
for (prop in arr){
    if (arr[prop] === "banana"){
       //add to new array
    }
}

Thoughts? JQuery and Underscore are both options to use.

like image 939
Evan Avatar asked Feb 04 '13 21:02

Evan


3 Answers

This is an easy job for Array.reduce(...):

function groupBy(arr, property) {   return arr.reduce(function(memo, x) {     if (!memo[x[property]]) { memo[x[property]] = []; }     memo[x[property]].push(x);     return memo;   }, {}); }  var o = groupBy(arr, 'type'); // => {orange:[...], banana:[...]} o.orange; // => [{"type":"orange","title":"First"},{"type":"orange","title":"Second"}] o.banana; // => [{"type":"banana","title":"Third"},{"type":"banana","title":"Fourth"}] 

Of course, if your target browser(s) do not support ECMAScript 262 5th edition then you'll have to implement "reduce" by yourself, or use a polyfill library, or choose another answer.

[Update] Here's a solution that should work with any version of JavaScript:

function groupBy2(xs, prop) {   var grouped = {};   for (var i=0; i<xs.length; i++) {     var p = xs[i][prop];     if (!grouped[p]) { grouped[p] = []; }     grouped[p].push(xs[i]);   }   return grouped; } 
like image 192
maerics Avatar answered Oct 09 '22 01:10

maerics


JQuery and Underscore are both options to use.

Underscore's groupBy does exactly what you need.

_.groupBy(arr, "type") 
like image 33
Bergi Avatar answered Oct 09 '22 00:10

Bergi


This assumes an array of objects:

function groupBy(array, property) {
    var hash = {};
    for (var i = 0; i < array.length; i++) {
        if (!hash[array[i][property]]) hash[array[i][property]] = [];
        hash[array[i][property]].push(array[i]);
    }
    return hash;
}

groupBy(arr,'type')  // Object {orange: Array[2], banana: Array[2]}
groupBy(arr,'title') // Object {First: Array[1], Second: Array[1], Third: Array[1], Fourth: Array[1]}
like image 26
Shmiddty Avatar answered Oct 09 '22 02:10

Shmiddty