Reputation: 57
I have an Array of JSON objects like so
var dataSet1 = [{
"id": "1",
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"version": "5",
"grade": "X"
}, {
"id": "2",
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"version": "5",
"grade": "A"
}, {
"id": "3",
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"version": "4",
"grade": "X"
},
{
"id": "4",
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"version": "5",
"grade": "A"
}];
I would like to loop through this data set and create a new array of objects that merge the objects with similar "grade" properties and preserves a list of their associated "id" and "version" values like so
OLD Objects with "grade" property equal to 'X'
{
"id": "1",
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"version": "5",
"grade": "X"
}
{
"id": "3",
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"version": "4",
"grade": "X"
}
NEW Object with "grade" property equal to 'X'
{
"ids":{"id":"1","id":"3"}
"engine": "Trident",
"browser": "Internet Explorer 4.0",
"platform": "Win 95+",
"versions":{ "version":"4", "version":"5"}
"grade": "X"
}
Im pretty sure I have to use the $.each and $.grep function like so
$.each(dataSet1, function (index, value) {
tsaGrade = dataSet1[index].grade;
result = $.grep(dataSet1, function (e) {
return e.grade == tsaGrade;
})
and placing the ids and versions in new arrays, but I get lost on how to prevent the each loop from excluding the values that is already grouped the next time it loops through the data set.
Upvotes: 4
Views: 2757
Reputation: 5124
If you're willing to use Underscore.js, this becomes pretty trivial.
Assuming data
is your original list of json objects, this will achieve what you're after:
var groups = [];
var by_grade = _.groupBy(data, function(obj) { return obj['grade'] });
_.each(by_grade, function(objs, grade) {
var group = {};
group['grade'] = grade;
group['ids'] = _.pluck(objs, 'id');
group['versions'] = _.pluck(objs, 'version');
// Use the following if the value is known to be
// the same for all grouped objects
group['platform'] = objs[0]['platform'];
// And the rest...
groups.push(group);
});
_.groupBy()
will group your objects by grade, resulting in two objects with the keys X
and A
, whose values are lists of objects with the corresponding grades. You can then loop over each of the two lists of objects, pluck
ing the required values so that they will be added as lists to your new object. Difficult to describe fully, but see the log messages on this Fiddle :)
Edit
Instead of objs['platform']
should be using objs[0]['platform']
for all attributes that you know are the same for items with the same grade.
Edit 2
Building from this, a better approach instead of _.each
would probably be _.map
:
groups = _.map(by_grade, function(objs, grade) {
return {
grade: grade,
browsers: _.pluck(objs, 'browser'),
ids: _.pluck(objs, 'id'),
versions: _.pluck(objs, 'id'),
engines: _.pluck(objs, 'engine')
// etc
}
});
Upvotes: 2