Вычисление сумм в сгруппированном массиве в JavaScript

#javascript

Вопрос:

Я пытаюсь сгенерировать новый массив людей с их общим количеством. Я смог отфильтровать суммы, основанные на людях. Кто-нибудь может, пожалуйста, помочь?

 mockData = [{
  name: 'John',
  title: 'Gas',
  amount: 20.10
}, {
  name: 'John',
  title: 'Taco bell',
  amount: 4.10
}, {
  name: 'Doe',
  title: 'Food',
  amount: 30.50
}, {
  name: 'Doe',
  title: 'Groceries',
  amount: 10.20
}, {
  name: 'Doe',
  title: 'Paint',
  amount: 5
}];

const distinctItems = [...new Map(mockData.map(item => [item.name, item])).values()].map(({
  name
}) => name);

const filterTotals = (expenses, person) =>
  expenses.filter(({
    name
  }) => name === person)

const result = distinctItems.map((name) => filterTotals(mockData, name));

console.log(result) 

Конечный результат, которого я ожидаю, таков

 [{name: 'John', total: 24.20}, {name: 'Doe', total: 45.7}]
 

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

1. функция уменьшения должна отлично работать там

Ответ №1:

Вы можете выполнить один цикл с данными и добавить amount к ним то же name самое .

 const
    data = [{ name: 'John', title: 'Gas', amount: 20.10 }, { name: 'John', title: 'Taco bell', amount: 4.10 }, { name: 'Doe', title: 'Food', amount: 30.50 }, { name: 'Doe', title: 'Groceries', amount: 10.20 }, { name: 'Doe', title: 'Paint', amount: 5 }],
    result = Array.from(
        data.reduce((m, { name, amount }) => m.set(name, (m.get(name) || 0)   amount), new Map),
        ([name, total]) => ({ name, total })
    );
    
console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

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

1. Могу я узнать, что здесь есть set и get какие функции?

2. они поступают из аккумулятора: Map

Ответ №2:

Уменьшите массив до объекта с ключом в качестве имени и значения в качестве общей суммы для этого имени, а затем вы можете использовать Object.entries для перебора ключа и значения

 const mockData = [{
  name: 'John',
  title: 'Gas',
  amount: 20.10
}, {
  name: 'John',
  title: 'Taco bell',
  amount: 4.10
}, {
  name: 'Doe',
  title: 'Food',
  amount: 30.50
}, {
  name: 'Doe',
  title: 'Groceries',
  amount: 10.20
}, {
  name: 'Doe',
  title: 'Paint',
  amount: 5
}];

const obj = mockData.reduce((map, obj) => {
  const {
    name,
    amount
  } = obj
  map[name] = name in map ? map[name]   amount : amount
  return map
}, {})
const result = Object.entries(obj).map(([key, value]) => ({
  name: key,
  total: value.toFixed(2)
}))
console.log('result', result) 

Ответ №3:

 mockData = [{
  name: 'John',
  title: 'Gas',
  amount: 20.10
}, {
  name: 'John',
  title: 'Taco bell',
  amount: 4.10
}, {
  name: 'Doe',
  title: 'Food',
  amount: 30.50
}, {
  name: 'Doe',
  title: 'Groceries',
  amount: 10.20
}, {
  name: 'Doe',
  title: 'Paint',
  amount: 5
}];

const totalAmountMap = mockData.reduce((accumulator, { name, amount }) => {
    accumulator[name] = (accumulator[name] || 0)   amount;
    return accumulator;
 }, {});

 const totalAmountArray = Object.keys(totalAmountMap).map((name) => ({
     name,
     total: totalAmountMap[name]
 }));

 console.log(totalAmountArray);