Как суммировать значения в объекте с вложенными массивами?

#javascript #json

Вопрос:

У меня есть следующая структура:

 groupedData = {  rice: [  {  name: 'white rice'  quantity: 2  category: 'rice'  },  {  name: 'brown rice'  quantity: 1  category: 'rice'  }  ],  water: [  {  name: 'sparkle water'  quantity: 1  category: 'water'  },  {  name: 'still water'  quantity: 1  category: 'water'  }  ],  tea: [{  name: 'green tea'  quantity: 1  category: 'water'  }],  }  

Чего я хочу добиться, так это иметь суммированное количество каждой категории, например: рис: 3, вода: 2, чай: 1

Я попробовал следующее:

 const sum = () =gt; {  let quantity = []  for (var property in groupedData) {  for (let i=0; ilt; groupedData[property].length; i  ){  quantity[property] = groupedData[property][i].quantity;  }  }  return quantity; }  

но он возвращает не суммированные данные, а только количество первого товара [rice: 2, water: 1, tea: 1]

Комментарии:

1. а) вы никогда ничего не суммируете (не добавляете) с помощью или = , вы только назначаете б) ваша функция этого не return делает в) если вы хотите иметь несколько сумм (по категориям), то вам нужна структура данных для их хранения вместо одной quantity переменной

2. @Bergi ой извините, я скопировал неправильную версию этой функции, я отредактировал вопрос. Теперь я не знаю, как добавить эти значения

Ответ №1:

Это основано на вашем вопросе.

 const groupedData = {  rice: [{  name: 'white rice',  quantity: 2,  category: 'rice',  },  {  name: 'brown rice',  quantity: 1,  category: 'rice',  }  ],  water: [{  name: 'sparkle water',  quantity: 1,  category: 'water',  },  {  name: 'still water',  quantity: 1,  category: 'water',  }  ],  tea: [{  name: 'green tea',  quantity: 1,  category: 'water',  }], }  const sum = () =gt; {  let quantity = {}  for (var property in groupedData) {  for (let i = 0; i lt; groupedData[property].length; i  ) {  quantity = {  ...quantity,  [property]: quantity[property] ? quantity[property]   groupedData[property][i].quantity : groupedData[property][i].quantity  }  }  }  return quantity; }  console.log(sum()); 

И это мой ответ с уменьшением

 const groupedData = {  rice: [{  name: 'white rice',  quantity: 2,  category: 'rice',  },  {  name: 'brown rice',  quantity: 1,  category: 'rice',  }  ],  water: [{  name: 'sparkle water',  quantity: 1,  category: 'water',  },  {  name: 'still water',  quantity: 1,  category: 'water',  }  ],  tea: [{  name: 'green tea',  quantity: 1,  category: 'water',  }], }  const sum = () =gt; {  let res = {}  for (var props in groupedData) {  const item = groupedData[props].reduce((acc, cur) =gt; {  acc  = cur.quantity;  return acc;  }, 0);  res[props] = item;  }  return res; }  console.log(sum()); 

Ответ №2:

Вы можете сделать что-то вроде этого:

 const result = Object.entries(groupedData).reduce((prev, [k, v]) =gt; {  const sums = {  ...prev,  [k]: v.reduce((p, c) =gt; p   c.quantity, 0),  }  return sums }, {})  

Вот полный фрагмент:

 const groupedData = {  rice: [{  name: 'white rice',  quantity: 2,  category: 'rice',  },  {  name: 'brown rice',  quantity: 1,  category: 'rice',  },  ],  water: [{  name: 'sparkle water',  quantity: 1,  category: 'water',  },  {  name: 'still water',  quantity: 1,  category: 'water',  },  ],  tea: [{  name: 'green tea',  quantity: 1,  category: 'water',  }, ], }  const result = Object.entries(groupedData).reduce((prev, [k, v]) =gt; {  const sums = {  ...prev,  [k]: v.reduce((p, c) =gt; p   c.quantity, 0),  }  return sums }, {})  console.log(result) 

Ответ №3:

Ваше решение не добавляет узлы. Просто добавьте значение quantity каждого узла

 const groupedData = {  rice: [  { name: 'white rice', quantity: 2, category: 'rice' },  { name: 'brown rice', quantity: 1, category: 'rice' }  ],  water: [  { name: 'sparkle water', quantity: 1, category: 'water' },  { name: 'still water', quantity: 1, category: 'water' }  ],  tea: [  { name: 'green tea', quantity: 1, category: 'water' }], };  const sum = () =gt; {  let quantity = {}  for (var property in groupedData) {  for (let i = 0; i lt; groupedData[property].length; i  ) {  quantity[property] = quantity[property] ? quantity[property] : 0;  quantity[property]  = groupedData[property][i].quantity;  }  }  return quantity; }; console.log(sum()); 

Вы также можете использовать Object.entries Array.forEach и Array.reduce для достижения этой цели.

 const groupedData = {  rice: [  { name: 'white rice', quantity: 2, category: 'rice' },  { name: 'brown rice', quantity: 1, category: 'rice' }  ],  water: [  { name: 'sparkle water', quantity: 1, category: 'water' },  { name: 'still water', quantity: 1, category: 'water' }  ],  tea: [  { name: 'green tea', quantity: 1, category: 'water' }], }; const sum = () =gt; {  let quantity = {};  Object.entries(groupedData).forEach(([key, value]) =gt; {  quantity[key] = value.reduce((acc, { quantity }) =gt; acc  = quantity, 0)  });  return quantity; }; console.log(sum()); 

Ответ №4:

и как один лайнер…

 var result = Object.keys(groupedData).reduce((prev, key) =gt; ({...prev,[key]: groupedData[key].reduce((total,item)=gt;total item.quantity,0)}),{});  console.log(result);  

использование Object.entries, возможно, более читабельно

 var result2 = Object.entries(groupedData).reduce((prev, [k, v]) =gt; ({...prev, [k]: v.reduce((total,item)=gt;total item.quantity,0)}),{});  console.log(result2);