Reputation: 95
I am trying to put the elements that have the same property value in Array(e.g., data) in a group as a new element and push the new element into a new Array(e.g., newData). How can I transform data to newData ?
data = [
{status: 0,name:'a'},
{status: 0,name:'b'},
{status: 1,name:'b'},
];
var newData = [
{
id: 0,
name: 'a',
services: [
{id: 'a', name: 'a',status: 0}
]
},
{
id: 1,
name: 'b',
services: [
{id: 'b', name: 'b',status: 0},
{id: 'b', name: 'b',status: 1},
]
}
]
Upvotes: 0
Views: 141
Reputation: 386654
You could use a hash table as reference to the group with the same name and push the actual item to services
.
var data = [{ status: 0, name: 'a' }, { status: 0, name: 'b' }, { status: 1, name: 'b' }],
grouped = data.reduce(function (hash) {
return function (r, a) {
if (!hash[a.name]) {
hash[a.name] = { id: a.name, name: a.name, services: [] };
r.push(hash[a.name]);
}
a.id = a.name;
hash[a.name].services.push(a);
return r;
};
}(Object.create(null)), []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With id
counting from zero.
var data = [{ status: 0, name: 'a' }, { status: 0, name: 'b' }, { status: 1, name: 'b' }],
grouped = data.reduce(function (hash, id) {
return function (r, a) {
if (!hash[a.name]) {
hash[a.name] = { id: id++, name: a.name, services: [] };
r.push(hash[a.name]);
}
a.id = a.name;
hash[a.name].services.push(a);
return r;
};
}(Object.create(null), 0), []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 4020
var data = [
{status: 0,name:'a'},
{status: 0,name:'b'},
{status: 1,name:'b'}
];
var finalData = [];
var i=0;
data.forEach(function(datum){
var matchingElem = finalData.find(function(elem){
return elem.name === datum.name;
});
if(matchingElem)
{
matchingElem.services.push({
"id":datum.name,
"name": datum.name,
"status": datum.status
});
}
else{
finalData.push({
"id":i++,
"name":datum.name,
"services": [{
"id":datum.name,
"name": datum.name,
"status": datum.status
}]
});
}
});
console.log(JSON.stringify( finalData ));
Upvotes: 3
Reputation: 3213
var data = [
{status: 0,name:'a'},
{status: 0,name:'b'},
{status: 1,name:'b'},
];
var id = 0;
var finalData = data.reduce(function(acc, cur) {
var elm = acc.find(e => {
return e.name === cur.name
});
if (elm) {
elm.services.push({
id: cur.name,
name: cur.name,
status: cur.status
})
} else {
acc.push({
id: id++,
name: cur.name,
services: [{
id: cur.name,
name: cur.name,
status: cur.status
}]
})
}
return acc;
}, []);
console.log(finalData)
Upvotes: 1
Reputation: 68393
Follow this approach
name
and array of statuses against it.DEMO
var data = [
{status: 0,name:'a'},
{status: 0,name:'b'},
{status: 1,name:'b'},
];
var map = {};
data.forEach( function(item){
map[ item.name ] = map[ item.name ] || [];
map[ item.name ].push( item );
});
var newData = Object.keys( map ).map(function(name, index){
var arr = map[ name ];
arr = arr.map( function(arrItem){ arrItem.id = arrItem.name; return arrItem });
return { id : index, name : name, services : arr };
});
console.log(newData);
Upvotes: 1
Reputation: 138317
data = [
{status: 0,name:'a'},
{status: 0,name:'b'},
{status: 1,name:'b'},
];
NewData=data.reduce((newobj,obj)=>((newobj[obj.name]=newobj[obj.name]||[]).push(obj),newobj),{});
NewData will be:
{
"a":[
{status: 0,name:'a'},
],
"b":[
{status: 0,name:'b'},
{status: 1,name:'b'},
]
}
http://jsbin.com/devucujaso/edit?console
You simply put every obj of the old array into the obj.name Array of the new obj, if it doesnt exist yet create a new array ( ||[]). Theres still some forming missing to get your desired result, but i think you can do that on your own...
Upvotes: 2