Reputation: 1108
I am getting this result from my API :
But any with the same id (like the last 2) i would like to be grouped in an object so there would be only 3 items in the array (0,1,2) and the last one would be nested within the last one because it has a duplicate ID. It is ordered in the correct format from the SQL so i would like it to keep it's order.
There could be up to 50 with the same id that might need to nest, i tried using an array and the key but cant get the desired result
if(data.length > 0){
console.log(value);
try{
if(value.id == s[key - 1].id){
console.log("match");
s.push(value);
} else {
orderobj.push(s);
}
} catch(ex){}
console.log(orderobj);
}
Upvotes: 1
Views: 2853
Reputation: 22524
You can use array#reduce
. You can add objects in an array sharing the same id
and then use Object.values()
to get all the objects.
var arr = [{id:'27', uid: '7', code: 'HV0010SML', productid: '1', datetime: '2017-10-06 15:57:17'},{id:'28', uid: '7', code: 'HV0010MED', productid: '1', datetime: '2017-10-06 15:57:17'},{id:'29', uid: '7', code: 'HV0010LGE', productid: '1', datetime: '2017-10-06 15:57:17'},{id:'29', uid: '7', code: 'HV0010LGE', productid: '1', datetime: '2017-10-06 15:57:17'}];
var combined = arr.reduce((hash, obj) => {
return obj.id in hash ? hash[obj.id].push(obj) : hash[obj.id] = [obj], hash;
}, Object.create(null));
var result = Object.values(combined);
console.log(result);
.as-console-wrapper{max-height: 100% !important}
Upvotes: 0
Reputation: 2085
Try this
var apiData = [
{id: 1, text: '1asdf'},
{id: 2, text: '2asdf'},
{id: 3, text: '3asdf'},
{id: 4, text: '4asdf'},
{id: 4, text: '5asdf'},
];
var result = [];
apiData.forEach((item) => {
var saved = result.find((innerArr) => {
return innerArr.find((innerItem) => innerItem.id === item.id) ? true : false;
})
if(saved){
saved.push(item);
} else {
result.push([item]);
}
})
console.log(result);
Upvotes: 0
Reputation: 5626
Since all of your like-ID's are sequential you can do a pretty simple check when creating a new collection from your API data. Just keep adding objects into an array until the ID's no longer match, then add that array into a parent array.
var apiData = [
{id: 1, text: '1asdf'},
{id: 2, text: '2asdf'},
{id: 3, text: '3asdf'},
{id: 4, text: '4asdf'},
{id: 4, text: '5asdf'},
];
var dataArray = [];
for(let i=0;i<apiData.length;++i) {
var dataItem = [];
dataItem.push(apiData[i]);
while(i < apiData.length-1 && apiData[i].id === apiData[i+1].id) {
++i
dataItem.push(apiData[i]);
}
dataArray.push(dataItem);
}
console.log('Final Array:', dataArray);
Upvotes: 3
Reputation: 104775
I would just make an object map with the ID as the key, and then an array of matching objects as the value. Then loop the object keys in order and create an array from all of that:
let objectMap = data.reduce(function(o, i) {
if (!o[i.id]) o[i.id] = [];
o[i.id].push(i)
return o;
}, {})
And concat:
let sortedKeys = Object.keys(objectMap).sort();
let groupedData = sortedKeys.reduce(function(d, k) {
d.push(objectMap[k]);
return d;
}, []); //return format: [[{id:1}],[{id:2}],[{id:3},{id:3}]
Upvotes: 1