Как объединить вложенный массив объектов в javascript с определенной формой

Я пытаюсь объединить массив объектов, суммируя итоги каждой пары ключ-значение в объекте итогов. Например, приведенный ниже массив даст один объект с totals объектом из 3 яблок и 5 апельсинов. Это должно быть динамично. Если бы груши были ключом к другому объекту, результирующий объект включал бы три ключа под объектом totals: яблоки, апельсины и груши.

Пример ввода:

[
  {
    summary: {
      totals: {
        apples: 2,
        oranges: 3
      }
    }
  },
  {
    summary: {
      totals: {
        apples: 1,
        oranges: 2
      }
    }
  }
]

Ожидаемый результат:

{
  summary:{
    totals:{
      apples:3,
      oranges:5
    }
  }
}

Что я пробовал:

function mergeObjects(arr) {
  let shape = {
    summary:{
      totals:{}
    }
  }
  
  return arr.reduce((prev, cur) => {
   if(cur.summary.totals.apples){
     shape.summary.totals.apples.push(cur.summary.totals.apples)
   }
  }, shape);
}
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
0
35
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий
  • Используя Array#reduce, выполните итерацию по массиву при обновлении объекта.
  • В каждой итерации, используя Object#entries и , перебираем текущие пары итогов и обновляем аккумулятор.

const arr = [
  { summary: { totals: { apples: 2, oranges: 3 } } },
  { summary: { totals: { apples: 1, oranges: 2 } } },
];

const res = arr.reduce((map, current) => {
  const { totals: currentTotals = {} } = current.summary ?? {};
  const { totals } = map.summary;
  Object.entries(currentTotals).forEach(([ key, value ]) => {
    totals[key] = (totals[key] ?? 0) + value;
  });
  return map;
}, { summary: { totals: {} } });

console.log(res);

Вы можете попробовать что-то вроде. Просто переберите массив и просуммируйте яблоки и апельсины.

const arr = [
  {
    summary: {
      totals: {
        apples: 2,
        oranges: 3,
      },
    },
  },
  {
    summary: {
      totals: {
        apples: 1,
        oranges: 2,
      },
    },
  },
];

function mergeObjects(arr) {
  let shape = {
    summary:{
      totals:{
      apples:0,
      oranges:0
      }
    }
  }
  
  arr.forEach(x => {
   if(x.summary.totals.apples){
     shape.summary.totals.apples += x.summary.totals.apples;
     shape.summary.totals.oranges += x.summary.totals.oranges;
   }
  });
  return shape;
}

let result = mergeObjects(arr);
console.log(result);

Второй вариант функции сокращения инициализирует значение.

А инициализированное значение можно использовать в prev!

[1] сохранить значение в предыдущем.

[2] prev может накапливать значения. Вы должны вернуться, чтобы использовать накопленное значение. Если не возвращено, значение будет неопределенным.

[3] яблоки не являются типом массива, поэтому вы не можете использовать метод push. это числовой тип, вы должны использовать числовой оператор.

function mergeObjects(arr) {
  const shape = {
    summary: {
      totals: {},
    },
  };

  return arr.reduce((prev, cur) => {
    const { apples, oranges } = cur.summary.totals;
    // [1]
    prev.summary.totals.apples
      // [3]
      ? (prev.summary.totals.apples += apples)
      : (prev.summary.totals.apples = apples);
    prev.summary.totals.oranges
      ? (prev.summary.totals.oranges += oranges)
      : (prev.summary.totals.oranges = oranges);
    // [2]
    return prev;
  }, shape);
}

подсказки!

  1. Использовать назначение деструктурирования
const { apples, oranges } = cur.summary.totals;
  1. Используйте тернарный оператор
prev.summary.totals.apples
      ? (prev.summary.totals.apples += apples)
      : (prev.summary.totals.apples = apples);
  • Сделайте код красивым!

Вы можете комбинировать Объект.записи() с Массив#уменьшить() и Массив.для каждого()

Код:

const data = [{summary: {totals: {apples: 2,oranges: 3}}},{summary: {totals: {apples: 1,oranges: 2}}}]

const result = data.reduce((a, c) => {
  Object
    .entries(c.summary.totals)
    .forEach(([k, v]) => a.summary.totals[k] += v)
  return a
},
{ summary: { totals: { apples: 0, oranges: 0 } } })

console.log(result)

Другие вопросы по теме