Gaz Smith
Gaz Smith

Reputation: 1108

JavaScript converting object with same id to array of objects

I am getting this result from my API :

enter image description here

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

Answers (4)

Hassan Imam
Hassan Imam

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

prabhatojha
prabhatojha

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

Ben
Ben

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

tymeJV
tymeJV

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

Related Questions