Перебор массива объектов 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 шт):
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)
}
Есть метод массива 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. В конце концов именно оно и будет возвращено из функции.
А вообще, почему здесь свойства с большой буквы?..
Нагляднее всего в таких случаях использовать 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);
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));
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 }