How can we change the structure of the below data object using JavaScript. Needs to categorize all the names under the std. Thanks in advance
[
{
"name": "Rohan",
"std": "3"
},
{
"name": "Jack",
"std": "2"
},
{
"name": "Peter",
"std": "2"
}
]
to
[
{
"std": "2",
"details": [
{
"name": "Jack"
},
{
"name": "Peter"
}
]
},
{
"std": "3",
"details": [
{
"name": "Rohan"
}
]
}
]
-
Refer following link, i think this should help you:- stackoverflow.com/questions/15279685/restructure-jsonMeet– Meet2016年05月21日 05:56:59 +00:00Commented May 21, 2016 at 5:56
4 Answers 4
The solution using Array.forEach, Array.map and Object.keys functions:
var arr = [{"name": "Rohan", "std": "3"}, { "name": "Jack", "std": "2" }, { "name": "Peter", "std": "2" }],
grouped = {}, result;
arr.forEach(function(obj){
var std = obj['std'];
if (this[std]) {
this[std]['details'].push({'name' : obj['name']});
} else {
this[std] = {'std' : std, 'details' : [{'name' : obj['name']}]};
}
}, grouped);
result = Object.keys(grouped).map((k) => grouped[k]);
console.log(JSON.stringify(result, 0, 4));
The output:
[
{
"std": "2",
"details": [
{
"name": "Jack"
},
{
"name": "Peter"
}
]
},
{
"std": "3",
"details": [
{
"name": "Rohan"
}
]
}
]
Comments
You can use reduce() method here
var data = [{
"name": "Rohan",
"std": "3"
}, {
"name": "Jack",
"std": "2"
}, {
"name": "Peter",
"std": "2"
}],
res = [],
kmap = {};
res = data.reduce(function(a, b) {
// check std value already in array using kmap object
if (kmap[b.std]) {
// if already exist then push name attribute in the details
a[kmap[b.std] - 1].details.push({
'name': b.name
});
} else {
// in else case push the new object
a.push({
'std': b.std,
'details': [{
'name': b.name
}]
});
kmap[b.std] = a.length; // storing the (index + 1) value to avoid 0 in if condition
}
return a;
}, []);
console.log(res);
For older browsers check polyfill option for reduce method.
Comments
Problems like this are good candidates for recursion. Here is one possible recursive solution. You can make it much prettier using a functional programming framework such as underscore.js.
var objs = [
{
"name": "Rohan",
"std": "3"
},
{
"name": "Jack",
"std": "2"
},
{
"name": "Peter",
"std": "2"
}
];
function categorize(objs) {
if (objs.length === 0) {
return [];
} else {
var first = objs.shift();
var categorized = categorize(objs);
for(var i = 0; i < categorized.length; i++) {
if (categorized[i].std === first.std) {
categorized[i].details.push({name: first.name});
break;
}
}
if(i === categorized.length) {
categorized.push({std: first.std, details: [{name: first.name}]});
}
return categorized;
}
}
var res = categorize(objs);
console.log(res);
Comments
If you're using lodash (I know the question didn't ask this and it's going to be slower, but it may be useful to someone :))
var data = [
{ "name": "Rohan", "std": "3" },
{ "name": "Jack", "std": "2" },
{ "name": "Peter", "std": "2" }
];
var grouped = _.chain(data)
.groupBy('std')
.map(function (people, std) {
return {
std: std,
details: _.map(people, function(person) {
return { name: person.name };
})
}
}).value();