Как сложить поля вложенных объектов

Есть объект:

{
    billOne: {
        apple: 1,
        orange: 2,
        pear: 3,
        melon: 4,
    },
    billTwo: {
        apple: 10,
        orange: 20,
        pear: 30,
        melon: 40,
    },
}

Необходимо получить объект вида:

{
    appleSumm: 11,
    orangeSumm: 22,
    peaSummr: 33,
    melonSumm: 44,
}

На ум ничего кроме двух циклов не приходит. Может быть есть способ решить задачу изящнее?


Ответы (2 шт):

Автор решения: Inventor

Почему 2 цилка? 1 достаточно:

let obj = {
    one: {a: 1, b: 1},
    two: {a: 1, b: 1}
}

let output = {a_sum: 0, b_sum: 0}

for (i in obj) {
    output.a_sum = output.a_sum + i.a
    output.b_sum = output.a_sum + i.b
}
→ Ссылка
Автор решения: vsemozhebuty

Мне кажется, как тут ни оформляй, всё равно внутри будет несколько переборов внутри перебора. Например, можно так:

const bills = {
    billOne: {
        apple: 1,
        orange: 2,
        pear: 3,
        melon: 4,
    },
    billTwo: {
        apple: 10,
        orange: 20,
        pear: 30,
        melon: 40,
    },
};

const sum = Object.values(bills).reduce(
  (acc, bill) => {
    for (const [name, price] of Object.entries(bill)) {
      const sumKey = `${name}Sum`;
      if (acc[sumKey] === undefined) acc[sumKey] = 0;
      acc[sumKey] += price;
    }
    return acc;
  },
  {},
);

console.log(sum);

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

const bills = {
    billOne: {
        apple: 1,
        orange: 2,
        pear: 3,
        melon: 4,
    },
    billTwo: {
        apple: 10,
        orange: 20,
        pear: 30,
        melon: 40,
    },
};

const sum = Object.values(bills).reduce(
  (acc, bill) => {
    for (const [name, price] of Object.entries(bill)) {
      acc[`${name}Sum`] += price;
    }
    return acc;
  },
  Object.fromEntries(
    Object.keys(Object.values(bills)[0]).map(key => [`${key}Sum`, 0])
  ),
);

console.log(sum);

→ Ссылка