Извините за заголовок, я даже не знаю, как сформулировать то, что здесь происходит.
Я работаю над программой отслеживания расходов в React, которая поддерживает несколько валют.Отслеживаемые расходы могут быть произвольно вложены в объект JSON.
entertainment: {
_values: {
USD: 23,
AUD: 5,
},
'food & drink': {
_values: {
AUD: 83,
},
'local bar': {
_values: {
AUD: 28,
USD: 2,
},
},
},
minigolf: {
_values: {
USD: 112,
},
}
}
В расходе может храниться сумма, хранящаяся непосредственно в нем, но она также может выступать в качестве «родительской» категории для дальнейших подробных суб-расходов.
Для отображения общей стоимостиРасход, который я написал пару функций: sumValues(values)
Суммирует массив _values
объектов (объект значения является хранилищем ключей и целых чисел) и 1010 *
totalExpense(expense)
ВозвращаетОбщая стоимость расходов.т. е. любой _values
, который он имеет, + totalExpense любых дочерних расходов.
Я думал, что написал бы их как чистые функции, но при рекурсивном вызове totalExpense()
первый дочерний элемент расхода возвращает неправильное итоговое значение.
totalExpense(entertainment);
//-> Object { USD: 137, AUD: 116 }
ОК
totalExpense(entertainment['food & drink']);
//-> Object { AUD: 111, USD: 2 }
ОК
totalExpense(entertainment);
totalExpense(entertainment['food & drink']);
//-> Object { AUD: 139, USD: 4 }
НЕ ОК
Я уже несколько часов копаюсь в этом коде,но по жизни я не вижу, что происходит:
sumValues = values => {
return values.reduce((acc, cur) => {
for (const currency in cur) {
acc[currency]
? (acc[currency] = acc[currency] + cur[currency])
: (acc[currency] = cur[currency]);
}
return acc;
});
};
totalExpense = expense => {
const values = [];
if (expense['_values']) {
values.push(expense['_values']);
}
const subExpenses = Object.keys(expense).filter(child => {
return child[0] !== '_';
});
if (subExpenses.length > 0) {
for (const subExpense of subExpenses) {
let subtotal = this.totalExpense(expense[subExpense]);
values.push(subtotal);
}
}
if (values.length) {
return this.sumValues(values);
} else {
throw Error('No values in this expense');
}
};
render() {
const entertainment = {
_values: {
USD: 23,
AUD: 5,
},
'food & drink': {
_values: {
AUD: 83,
},
'local bar': {
_values: {
AUD: 28,
USD: 2,
},
},
},
minigolf: {
_values: {
USD: 112,
},
},
};
console.log(this.totalExpense(entertainment));
console.log(this.totalExpense(entertainment['food & drink']));
console.log(this.totalExpense(entertainment['minigolf']));
return;
}