Home > Enterprise >  Merge list of dictionaries by id in javascript
Merge list of dictionaries by id in javascript

Time:11-10

I have the following input

[
        {
            "id": "abc",
            "data1": 3,
            "data2": "test1",
        },
        {
            "id": "abc",
            "data1": 4,
            "data2": "test1",
        },
        {
            "id": "xyz",
            "data1": 2,
            "data2": "test2",
        }
]

I would like to parse this list, convert the data1 to list and add all the data1 with similar id into it like the following to create new list.

[

        {
            "id": "abc",
            "data1": [3,4],
            "data2": "test1",
        },
        {
            "id": "abc",
            "data1": [2],
            "data2": "test2",
        }
]

I have tried a few ways like using map/reduce but none of my solution worked.

CodePudding user response:

const data = [
  {
    id: 'abc',
    data1: 3,
    data2: 'test1',
  },
  {
    id: 'abc',
    data1: 4,
    data2: 'test1',
  },
  {
    id: 'xyz',
    data1: 2,
    data2: 'test2',
  },
];

/**
 * To merge the array of objects by a key
 *
 * @param {any[]} objectArray The input object array
 * @param {string} mergeBy The key for merging the objects
 * @param {string} property The key to which the values should be aggregated
 * @returns
 */
const groupBy = (objectArray, mergeBy, property) =>
  Object.values(
    objectArray.reduce(
      (
        /** @type {{ [x: string]: {}; }} */ acc,
        /** @type {{ [x: string]: any; }} */ obj
      ) => {
        const key = obj[mergeBy];
        const curGroup = acc[key] ?? {};
        // if the key is already exists in the accumulator object
        if (curGroup?.[property] && obj?.[property]) {
          curGroup[property].push(obj[property]);
          return { ...acc, [key]: { ...curGroup } };
        }
        if (!curGroup?.[property] && obj?.[property]) {
          const data = { ...obj } ;
          data[property] = [];
          data[property].push(obj[property]);
          return { ...acc, [key]: { ...data } };
        }
      },
      {}
    )
  );

groupBy(data, 'id', 'data1');

CodePudding user response:

Thanks all for your help. I have solved using the following logic

let helper = {}
let result = labels.reduce(function(r, o) {
  var key = o.id
  var outputpDic = {
    'id': o.id,
    'data1': [o.data1],
    'data2': o.data2,
  }

  if (!helper[key]) {
    helper[key] = Object.assign({}, outputpDic)
    r.push(helper[key])
  } else {
    helper[key].data1.push(o.data1)
  }

  return r
}, [])
  • Related