У меня есть два массива объектов, и я хочу объединить их на основе разных свойств, а также объединить, если что-то не существует в списке.

Вот что у меня есть:

const data1 = [{
  name: 'A',
  id: 1
}, {
  name: 'B',
  id: 2
}]

const data2 = [{
  city: 'X',
  rowID: 1
}, {
  city: 'Y',
  rowID: 2
}, {
  city: 'Z',
  rowID: 3
}]

const result = _.map(data1, function(p) {
  return _.merge(
    p,
    _.find(data2, {
      rowID: p.id
    })
  )
})

console.log(result)

//Expected Result
/**[
  {
    "name": "A",
    "id": 1,
    "city": "X",
    "rowID": 1
  },
  {
    "name": "B",
    "id": 2,
    "city": "Y",
    "rowID": 2
  },
  {
    "name": "",
    "id": "",
    "city": 'Z',
    "rowID": 3
  }
]*/
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

Пожалуйста посоветуй.

1
a2441918 20 Янв 2021 в 22:00

2 ответа

Лучший ответ

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

const
    merge = data => {
        const
            pattern = {},
            map = new Map;

        data.forEach(([objects, key]) => {
            Object.keys(objects[0]).forEach(k => pattern[k] = '');
            objects.forEach(o => map.set(o[key], { ...map.get(o[key]), ...o }));
        });
        return Array.from(map.values(), o => ({ ...pattern, ...o }));
    },
    data1 = [{ name: 'A', id: 1 }, { name: 'B', id: 2 }],
    data2 = [{ city: 'X', rowID: 1 }, { city: 'Y', rowID: 2 }, { city: 'Z', rowID: 3 }],
    result = merge([[data1, 'id'], [data2, 'rwoID']]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2
Nina Scholz 20 Янв 2021 в 19:42

Объедините массивы, сгруппируйте их по id или rowId, объедините все объекты и сопоставьте значения с пустыми строками, сопоставьте объект групп и объедините каждую группу со значениями по умолчанию для объекта (включая пустые по умолчанию id и name).

const { concat, groupBy, mapValues, map, merge } = _

const fn = (keys, ...arrs) => {
  const items = concat(...arrs);
  const defaults = mapValues(merge({}, ...items), () => '');

  return map(
    groupBy(items, o => keys.reduce((v, key) => v ?? o[key], null)),
    group => merge({}, defaults, ...group)
  )
}

const data1 = [{"name":"A","id":1},{"name":"B","id":2}]

const data2 = [{"city":"X","rowID":1},{"city":"Y","rowID":2},{"city":"Z","rowID":3}]

const result = fn(['id', 'rowID'], data1, data2)

console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>
0
Ori Drori 20 Янв 2021 в 21:00