Building Hash by Grouping Array of Objects Based on a Property of the Items

Building Hash by grouping array of objects based on a property of the items

Ruby has anticipated your need, and has got you covered with Enumerable#group_by:

irb(main):001:0> aers = %w(a b c d ab bc de abc)
#=> ["a", "b", "c", "d", "ab", "bc", "de", "abc"]

irb(main):002:0> aers.group_by{ |s| s.size }
#=> {1=>["a", "b", "c", "d"], 2=>["ab", "bc", "de"], 3=>["abc"]}

In Ruby 1.9, you can make this even shorter with:

irb(main):003:0> aers.group_by(&:size)
#=> {1=>["a", "b", "c", "d"], 2=>["ab", "bc", "de"], 3=>["abc"]}

How to group objects in an array based on a common property into an array of arrays

Just take a hash table and group by year and take the values from the hash table.

Bonus: A sorted result, because the keys of the object are sorted, if the keys could be read as indices of an array.

var films = [{ name: 'film 1', year: '1992' }, { name: 'film 2', year: '1992' }, { name: 'film 3', year: '1995' }, { name: 'film 4', year: '1995' }, { name: 'film 5', year: '1995' }, { name: 'film 6', year: '1998' }, { name: 'film 7', year: '1998' }],    grouped = Object.values(        films.reduce((r, o) => {            (r[o.year] = r[o.year] || []).push(o);            return r;        }, {})    );
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How can I group an array of objects by key?

Timo's answer is how I would do it. Simple _.groupBy, and allow some duplications in the objects in the grouped structure.

However the OP also asked for the duplicate make keys to be removed. If you wanted to go all the way:

var grouped = _.mapValues(_.groupBy(cars, 'make'),
clist => clist.map(car => _.omit(car, 'make')));

console.log(grouped);

Yields:

{ audi:
[ { model: 'r8', year: '2012' },
{ model: 'rs5', year: '2013' } ],
ford:
[ { model: 'mustang', year: '2012' },
{ model: 'fusion', year: '2015' } ],
kia:
[ { model: 'optima', year: '2012' } ]
}

If you wanted to do this using Underscore.js, note that its version of _.mapValues is called _.mapObject.

Group objects by multiple properties in array then sum up their values

Use Array#reduce with a helper object to group similar objects. For each object, check if the combined shape and color exists in the helper. If it doesn't, add to the helper using Object#assign to create a copy of the object, and push to the array. If it does, add it's values to used and instances.

var arr = [{"shape":"square","color":"red","used":1,"instances":1},{"shape":"square","color":"red","used":2,"instances":1},{"shape":"circle","color":"blue","used":0,"instances":0},{"shape":"square","color":"blue","used":4,"instances":4},{"shape":"circle","color":"red","used":1,"instances":1},{"shape":"circle","color":"red","used":1,"instances":0},{"shape":"square","color":"blue","used":4,"instances":5},{"shape":"square","color":"red","used":2,"instances":1}];
var helper = {};var result = arr.reduce(function(r, o) { var key = o.shape + '-' + o.color; if(!helper[key]) { helper[key] = Object.assign({}, o); // create a copy of o r.push(helper[key]); } else { helper[key].used += o.used; helper[key].instances += o.instances; }
return r;}, []);
console.log(result);

Most efficient method to groupby on an array of objects

If you want to avoid external libraries, you can concisely implement a vanilla version of groupBy() like so:

var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};

console.log(groupBy(['one', 'two', 'three'], 'length'));

// => {"3": ["one", "two"], "5": ["three"]}

Group array of javascript objects based on value into there own sub array of objects

You could use a closure over a hash table for the same email address and their items.

var data = [{ email: "alex@test.com", fn: "Alex", sn: "McPherson", phone: "01233xxxxx", hours: "40", rate: "20", amount: "200", vat: "60", agency: "test", start: "08/06/2017", end: "10/06/2017" }, { email: "mike@test.com", fn: "Mike", sn: "Mann", phone: "01233xxxxx", hours: "50", rate: "70", amount: "500", vat: "90", agency: "test", start: "08/06/2017", end: "10/06/2017" }, { email: "fred@test.com", fn: "Fred", sn: "Frogg", phone: "01233xxxxx", hours: "80", rate: "90", amount: "800", vat: "100", agency: "test", start: "08/06/2017", end: "10/06/2017" }, { email: "alex@test.com", fn: "Alex", sn: "McPherson", phone: "01233xxxxx", hours: "90", rate: "30", amount: "900", vat: "120", agency: "test", start: "08/06/2017", end: "10/06/2017" }],    result = data.reduce(function (hash) {        return function (r, o) {            if (!hash[o.email]) {                hash[o.email] = [];                r.push(hash[o.email]);            }            hash[o.email].push(o)            return r;        };    }(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

javascript - grouping objects by properties

You could group the items and the concat all groups in a single array.

It works by generating an object with the group as property an the items as items in the array.

In the next step, the object's values are taken and a new array is generated by concatination of the items with Array#reduce.

{                                                                              // hash
"Technical detals": [
{
name: "Display",
group: "Technical detals",
id: "60",
value: "4"
},
{
name: "OS",
group: "Technical detals",
id: "37",
value: "Apple iOS"
}
],
Manufacturer: [
{
name: "Manufacturer",
group: "Manufacturer",
id: "58",
value: "Apple"
}
]
}

var data = [{ name: "Display", group: "Technical detals", id: "60", value: "4" }, { name: "Manufacturer", group: "Manufacturer", id: "58", value: "Apple" }, { name: "OS", group: "Technical detals", id: "37", value: "Apple iOS" }],    groups = Object.create(null),    result = [];
data.forEach(function (a) { groups[a.group] = groups[a.group] || []; groups[a.group].push(a); });
result = Object.keys(groups).reduce(function (r, k) { return r.concat(groups[k]);}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

javascript | Object grouping

Try with something like this:

function groupBy(collection, property) {
var i = 0, val, index,
values = [], result = [];
for (; i < collection.length; i++) {
val = collection[i][property];
index = values.indexOf(val);
if (index > -1)
result[index].push(collection[i]);
else {
values.push(val);
result.push([collection[i]]);
}
}
return result;
}

var obj = groupBy(list, "group");

Keep in mind that Array.prototype.indexOf isn't defined in IE8 and older, but there are common polyfills for that.



Related Topics



Leave a reply



Submit