Reputation: 4748
I have an array generated by nest
method in d3.js
Can anyone suggest a javascript/jQuery way of grouping the objects in the values
property by category
?
var data = [
{
"key": "0",
"values": [
{
"category": "phone",
"brand": "Sony",
"brand_id": "0",
"name": "item A",
"id": "551",
"point": "600"
},
{
"category": "software",
"brand": "Sony",
"brand_id": "0",
"name": "item D",
"id": "51",
"point": "800"
},
{
"category": "phone",
"brand": "Sony",
"brand_id": "0",
"name": "item E",
"id": "52",
"point": "1800"
}
]
},
{
"key": "0",
"values": [
{
"category": "software",
"brand": "Microsoft",
"brand_id": "1",
"name": "item B",
"id": "54",
"point": "800"
},
{
"category": "phone",
"brand": "Microsoft",
"brand_id": "1",
"name": "item B",
"id": "60",
"point": "200"
},
{
"category": "phone",
"brand": "Microsoft",
"brand_id": "1",
"name": "item T",
"id": "30",
"point": "600"
},
{
"category": "software",
"brand": "Microsoft",
"brand_id": "1",
"name": "item N",
"id": "90",
"point": "500"
}
]
}
];
Here's a desired result:
[
{
"key": "0",
"values": [
{
"phone": [
{
"category": "phone",
"brand": "Sony",
"brand_id": "0",
"name": "item A",
"id": "551",
"point": "600"
},
{
"category": "phone",
"brand": "Sony",
"brand_id": "0",
"name": "item E",
"id": "52",
"point": "1800"
}
],
"software": [
{
"category": "software",
"brand": "Sony",
"brand_id": "0",
"name": "item D",
"id": "51",
"point": "800"
}
]
}
]
},
{
"key": "0",
"values": [
{
"phone": [
{
"category": "phone",
"brand": "Microsoft",
"brand_id": "0",
"name": "item B",
"id": "80",
"point": "54"
},
{
"category": "phone",
"brand": "Microsoft",
"brand_id": "0",
"name": "item D",
"id": "52",
"point": "1800"
}
],
"software": [
{
"category": "software",
"brand": "Microsoft",
"brand_id": "0",
"name": "item G",
"id": "41",
"point": "800"
},
{
"category": "software",
"brand": "Microsoft",
"brand_id": "0",
"name": "item L",
"id": "42",
"point": "900"
}
]
}
]
}
]
The following code doesn't work. I guess it's because grouped[t.category] = []
is defined in every loop. The previous item would be overwritten by the last one. If I didn't defined it, I would get a grouped[t.category]
undefined error:
grouped = {};
data.forEach(function(d){
d.values.map(function(t){
grouped[t.category] = [];
grouped[t.category].push({name:t.name,tid:t.id,point:parseInt(t.point)});
})
})
Upvotes: 2
Views: 4572
Reputation: 531
I'm familiar with underscore.js:
var desireResult = _.map(data, function(obj){
obj.values = _.groupBy(obj.values, 'category');
return obj;
});
Hope it will help you !
Upvotes: 1
Reputation: 185
You can solve it this way using lodash or similar library
_.map(data, function(x){
return _.assign({}, x, {values: _.groupBy(x.values, 'category')})
})
Upvotes: 3
Reputation: 897
You can try this: jsfiddle
var result = data.map(function ( record ) {
return {
key: record.key,
values: [ groupBy( 'category', record.values ) ]
};
})
function groupBy ( key, arr ) {
var groups = {};
arr.forEach(function ( el ) {
var keyVal = el[ key ];
if ( !keyVal ) return;
if ( groups[ keyVal ] )
groups[ keyVal ].push( el );
else
groups[ keyVal ] = [ el ];
});
return groups;
}
Upvotes: 1
Reputation: 77482
Try this
var grouped;
data.forEach(function(d) {
grouped = {};
d.values.forEach(function(t) {
if (!grouped[t.category]) {
grouped[t.category] = [];
}
grouped[t.category].push({
name: t.name,
tid: t.id,
point: parseInt(t.point)
});
})
d.values = grouped;
});
Upvotes: 2