Перебор массива объектов js

Не хватает знаний, чтобы решить задачу. Необходимо перебрать массив из объектов и получить из него другой массив, с результатом обработки. Дан массив объектов, вида:

    [
  {
    Method: 'BankCard',
    Destination: '4111111111111111',
    Description: 'Банковская карта 16 знаков',
    Amount: 11,
    Account: 'RUB'
  },
  {
    Method: 'BankCard',
    Destination: '411111111111111111',
    Description: 'Банковская карта 18 знаков',
    Amount: 12,
    Account: 'RUB'
  },
  {
    Method: 'BankCard',
    Destination: '4222222222222222;CARDHOLDER NAME',
    Description: 'Банковская карта 16 знаков, Cardholder Name',
    Amount: 13,
    Account: 'RUB'
  },
  {
    Method: 'BankCard',
    Destination: '4333333333333333;',
    Description: 'Банковская карта 16 знаков, пустой Cardholder Name',
    Amount: 14,
    Account: 'RUB'
  },
  {
    Method: 'Mobile',
    Destination: '72131231231',
    Description: 'Телефон 11 знаков, 7 без плюса',
    Amount: 15,
    Account: 'RUB'
  },
  {
    Method: 'WMR',
    Destination: 'R123456789101',
    Description: 'WMR',
    Amount: 16,
    Account: 'RUB'
  },
  {
    Method: 'YandexMoney',
    Destination: '12313123132131200000',
    Description: 'YandexMoney',
    Amount: 17,
    Account: 'RUB'
  }
]

Массив может иметь другие значения. Задача обработать массив таким образом, чтобы получить результат обработки с суммарными данными. Нужно узнать какое количество операций и какая сумма по каждому Method. Например метод BankCard имеет 4 операции и общую сумму 50. Метод WMR имеет 1 операцию и общую сумму 16. Результат обработки записать в массив, вида:

[
  {
    Method: 'name',
    Length: length,
    Amount: summ
  },
  {
    Method: 'name',
    Length: length,
    Amount: summ
  }
]

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

Автор решения: frozencoast
function calculate (data) {
    let result = {};

  for (let i = 0, j = data.length; i < j; i++) {
    if (!(data[i].Method in result)) {
        result[data[i].Method] = {
        Method: data[i].Method,
        Length: 0,
        Amount: 0
      };
    }
    result[data[i].Method].Length++;
    result[data[i].Method].Amount += data[i].Amount;
  }

  return Object.values(result)
}
→ Ссылка
Автор решения: artomich

Есть метод массива reduce. С ним задача решается следующим образом:

const reducer = (arr) => {
    return arr.reduce((last, now)=>{
         for (let item of last) {
              if (item.Method === now.Method) {
                  item.Length++;
                  item.Amount += now.Amount;
                  return last;
              }
         };
         last.push({Method: now.Method, Amount: now.Amount, Length: 1});
         return last;
    }), []);
}

Reduce работает так: в каждой итерации доступна переменная last - ее возвращает предыдущая итерация или, если цикл только начался, это значение по умолчанию (в данном случае пустой массив), - а также переменная now - непосредственно элемент массива, на котором сейчас цикл. Так, можно с каждой итерацией сокращать, видоизменять, редуцировать массив, возвращая новое значение last. В конце концов именно оно и будет возвращено из функции.

А вообще, почему здесь свойства с большой буквы?..

→ Ссылка
Автор решения: teran

Нагляднее всего в таких случаях использовать Array.reduce, по крайней мере это сразу говорит читающему код, что вы каким-то образом сжимаете массив, группируете его, так что для понимая кода это проще.

const data = [{Method:'BankCard',Destination:'4111111111111111',Description:'Банковская карта 16 знаков',Amount:11,Account:'RUB'},{Method:'BankCard',Destination:'411111111111111111',Description:'Банковская карта 18 знаков',Amount:12,Account:'RUB'},{Method:'BankCard',Destination:'4222222222222222;CARDHOLDER NAME',Description:'Банковская карта 16 знаков, Cardholder Name',Amount:13,Account:'RUB'},{Method:'BankCard',Destination:'4333333333333333;',Description:'Банковская карта 16 знаков, пустой Cardholder Name',Amount:14,Account:'RUB'},{Method:'Mobile',Destination:'72131231231',Description:'Телефон 11 знаков, 7 без плюса',Amount:15,Account:'RUB'},{Method:'WMR',Destination:'R123456789101',Description:'WMR',Amount:16,Account:'RUB'},{Method:'YandexMoney',Destination:'12313123132131200000',Description:'YandexMoney',Amount:17,Account:'RUB'}];

let result = data.reduce(function(acc,v){
           if(!acc[v.Method]){ 
               acc[v.Method] = { 
                   method: v.Method, 
                   sum: 0, 
                   count: 0 
               };
           }
           acc[v.Method].count++;
           acc[v.Method].sum += v.Amount;
           return acc;
       }, {});
       
console.log(result);       

→ Ссылка
Автор решения: IvaMuxa

let aaaa =  [  {Method: 'BankCard',    Destination: '4111111111111111',    Description: 'Банковская карта 16 знаков',    Amount: 11,    Account: 'RUB'  },  {    Method: 'BankCard',    Destination: '411111111111111111',    Description: 'Банковская карта 18 знаков',    Amount: 12,    Account: 'RUB'  },  {    Method: 'BankCard',    Destination: '4222222222222222;CARDHOLDER NAME',    Description: 'Банковская карта 16 знаков, Cardholder Name',    Amount: 13,    Account: 'RUB'  },  {    Method: 'BankCard',    Destination: '4333333333333333;',    Description: 'Банковская карта 16 знаков, пустой Cardholder Name',    Amount: 14,    Account: 'RUB'  },  {    Method: 'Mobile',    Destination: '72131231231',    Description: 'Телефон 11 знаков, 7 без плюса',    Amount: 15,    Account: 'RUB'  },  {    Method: 'WMR',    Destination: 'R123456789101',    Description: 'WMR',    Amount: 16,    Account: 'RUB'  },  {    Method: 'WMR',    Destination: 'R123456789101',    Description: 'WMR',    Amount: 111,    Account: 'RUB'  }]

function countMethods(a){
  let b = {};
  a.forEach(p => {
    if( b.hasOwnProperty(p.Method) ){
      b[p.Method].Amount += p.Amount;
      b[p.Method].Length ++;
    }else{
      b[p.Method] = {"Method": p.Method, "Length":1, "Amount": p.Amount}
    }
  });
  return Object.values(b);
}

console.log(countMethods(aaaa));

→ Ссылка
Автор решения: Qwertiy

var originalData = [
  { Method: 'BankCard',      Destination: '4111111111111111',                   Description: 'Банковская карта 16 знаков',                           Amount: 11,   Account: 'RUB' },
  { Method: 'BankCard',      Destination: '411111111111111111',                 Description: 'Банковская карта 18 знаков',                           Amount: 12,   Account: 'RUB' },
  { Method: 'BankCard',      Destination: '4222222222222222;CARDHOLDER NAME',   Description: 'Банковская карта 16 знаков, Cardholder Name',          Amount: 13,   Account: 'RUB' },
  { Method: 'BankCard',      Destination: '4333333333333333;',                  Description: 'Банковская карта 16 знаков, пустой Cardholder Name',   Amount: 14,   Account: 'RUB' },
  { Method: 'Mobile',        Destination: '72131231231',                        Description: 'Телефон 11 знаков, 7 без плюса',                       Amount: 15,   Account: 'RUB' },
  { Method: 'WMR',           Destination: 'R123456789101',                      Description: 'WMR',                                                  Amount: 16,   Account: 'RUB' },
  { Method: 'YandexMoney',   Destination: '12313123132131200000',               Description: 'YandexMoney',                                          Amount: 17,   Account: 'RUB' },
]

var newData = Object.create(null)

for (let { Method, Amount } of originalData) {
  if (newData[Method]) {
    ++newData[Method].Count
    newData[Method].Amount += Amount
  } else {
    newData[Method] = { Method, Count: 1, Amount }
  }
}

newData = Object.values(newData)

console.log(newData)
.as-console-wrapper.as-console-wrapper { max-height: 100vh }

→ Ссылка