Объединить дубликаты объектов в массиве - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть массив, как показано ниже:

original = [
{
 id:1,
 value1 : 500
},
{
 id:1,
 value2 : 600
},
{
 id:2,
 value1 : 700
},
{
 id:3,
 value2 : 750
}
];

Я хочу объединить дубликаты объектов в вышеуказанном массиве и хочу получить окончательный выходной массив, как показано ниже:

finalArr = [
 {
  id:1,
  value1:500,
  value2:600
},
{
 id:2,
 value1:700,
 value2:null
},
{
 id: 3,
 value1: null,
 value2:750
}
];

Как можноЯ добился этого с помощью JavaScript или TypeScript?

Ответы [ 4 ]

0 голосов
/ 21 февраля 2019

Вы можете взять Map и собрать все объекты с одинаковым id и получить в результате только значения карты.

var original = [{ id: 1, value1: 500 }, { id: 1, value2: 600 }, { id: 2, value1: 700 }, { id: 3, value2: 750 }],
    template = { id: null, value1: null, value2: null },
    result = Array.from(
        original
            .reduce(
                (m, o) => m.set(o.id, Object.assign({}, m.get(o.id) || template, o)),
                new Map
            )
            .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 21 февраля 2019

Вы можете использовать уменьшение, комбинацию карт

const original = [
    {
        id:1,
        value1 : 500
    },
    {
        id:1,
        value2 : 600
    },
    {
        id:2,
        value1 : 700
    },
    {
        id:3,
        value2 : 750
    }
];

const res = [...original.reduce(
    (a, b) => a.set(b.id, Object.assign((a.get(b.id) || {value2: null, value1: null, id: null}), b)),
    new Map
).values()];

console.log(res);
0 голосов
/ 21 февраля 2019

вы можете использовать обычный forEach,

let result = [];
original.forEach(elem => {
  let match = result.find(r => r.id === elem.id);
  if(match) {
    Object.assign(match, elem);
  } else {
    result.push(elem);
  }
});
0 голосов
/ 21 февраля 2019

Вы можете использовать функцию lodash uniq или uniqBy

original = _.uniq(original);

или

original = _.uniqBy(original, 'id');

В противном случае вы можете использовать уменьшение для проверки

let original = [
    {
        id: 1,
        value1: 500
    },
    {
        id: 1,
        value2: 600
    },
    {
        id: 2,
        value1: 700
    },
    {
        id: 3,
        value2: 750
    }
];

original = original.reduce((sum, val) => {
    for (let i in sum) {
        if (sum[i].id === val.id) {
            return sum;
        }
    }
    sum.push(val);
    return sum;
}, []);
...