Home > OS >  JS: find and merge similar objects in array by key
JS: find and merge similar objects in array by key

Time:05-11

I have an array of data. I need to find corresponding objects by code field and merge them. How can these be done?

const data = [
    {
      id: 'K1',
      code: 'KBP',
      zone: 'zone-k1'
    },
    {
      id: 'K2',
      code: 'KBP',
      zone: 'zone-k2'
    },
    {
      id: 'H',
      code: 'HCL',
      zone: 'zone-h'
    }
]


const expected = [
    {
      id: ['K1', 'K2'],
      code: 'KBP',
      zone: ['zone-k1', 'zone-k2']
    },
    {
      id: 'H',
      code: 'HCL',
      zone: 'zone-h'
    }
]

I've tried using lodash uniqBy and groupBy, but no success. I assume it should be done via reduce:

const res = () => {
    const similar = data.reduce((item, acc) => {
    return item.id === acc.id;
  })
}

CodePudding user response:

You could use Array.prototype.reduce and group the data by code.

const data = [
    {
      gateId: 'K1',
      code: 'KBP',
      zone: 'zone-k1'
    },
    {
      gateId: 'K2',
      code: 'KBP',
      zone: 'zone-k2'
    },
    {
      gateId: 'H',
      code: 'HCL',
      zone: 'zone-h'
    }
];

const dataset = data.reduce((acc, curr) => {
  if (acc[curr.code] === undefined) {
    acc[curr.code]  = {
      code: curr.code,
      id: [curr.gateId],
      zone: [curr.zone],
    }
  } else {
    acc[curr.code].id.push(curr.gateId)
    acc[curr.code].zone.push(curr.zone)
  }
  
  return acc;
}, {});

const res = Object.values(dataset);


console.log(res);
.as-console-wrapper{ min-height: 100vh !important; top: 0}

Fore more you could see this answer

CodePudding user response:

You can use Array.prototype.reduce and group the objects by their code.

Note: As per the OP, for codes that only have a single id, the id field needs to a string and not an array and this answer sticks to that.

const data = [
  { id: "K1", code: "KBP", zone: "zone-k1" },
  { id: "K2", code: "KBP", zone: "zone-k2" },
  { id: "K3", code: "KBP", zone: "zone-k3" },
  { id: "H", code: "HCL", zone: "zone-h" },
];

const output = Object.values(
  data.reduce((o, d) => {
    const temp = o[d.code];
    if (temp) {
      if (Array.isArray(temp?.id)) {
        temp.id.push(d.id);
        temp.zone.push(d.zone);
      } else {
        temp.id = [temp.id, d.id];
        temp.zone = [temp.zone, d.zone];
      }
    } else {
      o[d.code] = d;
    }
    return o;
  }, {})
);

console.log(output);

CodePudding user response:

You could group and take the wanted properties for the groups.

const
    data = [{ id: 'K1', code: 'KBP', zone: 'zone-k1' }, { id: 'K2', code: 'KBP', zone: 'zone-k2' }, { id: 'H', code: 'HCL', zone: 'zone-h' }],
    result = _(data)
        .groupBy('code')
        .map((items, code) => ({
            id: _.map(items, 'id'),
            code,
            zone: _.map(items, 'zone'),
         }))
        .value();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

  • Related