yuumatov
@yuumatov
FrontEnd разработчик, минималист

Как сформировать массив объектов исходя из 2-х других массивов объектов?

Есть 2 массива объектов.
Первый (данные пришли с бека):

[
    {
        "id": 55,
        "name": "region",
        "value": "1",
    },
    {
        "id": 56,
        "name": "age",
        "value": "2",
    }
]

Второй (данные которые мы добавили или изменили на клиенте):

[
    {
        "name": "range",
        "value": "Год"
    },
    {
        "name": "region",
        "value": "11"
    },
    {
        "name": "age",
        "value": "22"
    }
]

Нужно дополнить второй массив объектов, данными (добавить параметр ID объекту) из первого, чтобы получилось так:

[
    {
        "name": "range",
        "value": "Год"
    },
    {
        "id": 55,
        "name": "region",
        "value": "11"
    },
    {
        "id": 56,
        "name": "age",
        "value": "22"
    }
]
  • Вопрос задан
  • 128 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Сначала из первого массива сделаем объект, где значениями будут его элементы, а ключами - значения их, элементов, свойства name:

const obj1 = Object.fromEntries(arr1.map(n => [ n.name, n ]));

// или

const obj1 = arr1.reduce((acc, n) => (acc[n.name] = n, acc), {});

Затем можно собрать новый массив:

const newArr2 = arr2.map(n => ({ ...obj1[n.name], ...n }));

// или

const newArr2 = [];
for (let i = 0; i < arr2.length; i++) {
  newArr2.push(Object.assign({}, obj1[arr2[i].name], arr2[i]));
}

Или обновить существующий:

arr2.forEach(n => Object
  .entries(obj1[n.name] ?? {})
  .forEach(([ k, v ]) => Object.hasOwn(n, k) || (n[k] = v))
);

// или

for (const n of arr2) {
  const obj = obj1[n.name];
  for (const k in obj) {
    if (!n.hasOwnProperty(k)) {
      n[k] = obj[k];
    }
  }
}

UPD. Вынесено из комментариев:

можно ли исключить объекты у которых не изменился value? То есть что бы этих объектов не было в итоговом массиве.

const newArr2 = arr2.reduce((acc, n) => (
  obj1[n.name]?.value !== n.value && acc.push({ ...obj1[n.name], ...n }),
  acc
), []);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
GreyCrew
@GreyCrew
Full-stack developer
Есть ещё вариант:

const combinedArray = [
    ...array2,
    ...array1.filter(a1 => !array2.some(a2 => a2.name === a1.name))
].map(obj => ({
    ...obj,
    ...(array1.find(a1 => a1.name === obj.name) || {})
}));
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы