Home > Blockchain >  How to merge different properties into an object which has same id?
How to merge different properties into an object which has same id?

Time:08-10

let data = [{id:1, value:10}, {id:2, value:20}, {id:1, name:’test’}]

Output i want is:

data = [{id:1, value:10, name:’test’}, {id:2, value:20}]

How to achieve this ? Please help. Thanks in advance

CodePudding user response:

You can use reduce method to accumulate the array, then you can try findIndex if there is an item with this id exist in the accumulator if the index not equal -1 that's mean the item exist, So, if exist you can group the properties with rest operator, if not you can just push that item in the accumlator

let data = [{id:1, value:10}, {id:2, value:20}, {id:1, name:'test'}]

const result = data.reduce((acc, item) => {
   const index = acc.findIndex(i => i.id === item.id);
   index !== -1 ? (acc[index] = {...acc[index], ...item}) : acc.push(item)
   return acc
}, [])


console.log(result)

CodePudding user response:

The best possible way that I could come up with is using the Lodash's groupBy() method.

First you club all the objects basis on the id, and then keep merging all the objects with the same id.

import _ from "lodash";

let data = [
  {
    id: 1,
    value: 10
  },
  {
    id: 2,
    value: 20
  },
  {
    id: 1,
    name: "test"
  }
];

const groupedData = _.groupBy(data, "id");

const newData = Object.keys(groupedData).map((key) => {
  let res = {};
  groupedData[key].forEach((obj) => {
    res = { ...res, ...obj };
  });
  return res;
});

console.log(newData);

You can access the working sandbox here.

CodePudding user response:

The question has been answered already and I actually came up with almost exactly the same code as Mina, although it might be a bit hard to understand at first, here's a code sample that is probably a bit easier to understand :

let data = [{id:1, value: 10},{id:2, value: 20}, {id:1, name: 'test'}, {id:1, lastname: 'test2'}];

let transformedData = [];
for (const element of data) {
    let matchedIndex = transformedData.findIndex(x => x.id === element.id);
    if (matchedIndex < 0) {
    matchedIndex = transformedData.length;
    transformedData.push(element);
    }
   
   transformedData[matchedIndex] = {...transformedData[matchedIndex], ...element};
  }

console.log("merged result" , transformedData);

It starts with an empty list and everytime an item is found that isn't matched yet it adds it to the list. If it already exist in the list it just expands it with the additional data.

Keep in mind that in the end it does the same thing as the reduce approach highlighted by Mina.

CodePudding user response:

let data = [{id:1, value:10}, {id:2, value:20}, {id:1, name:"test"}];

const cache={};

for (let ele of data) {
    const {id}=ele;
    cache[id] = Object.assign({},cache[id],ele);
}

console.log(Object.values(cache));

  • Related