Если вы заинтересованы в решении с использованием Ramda, вот предложение:
const {
pipe,
mergeWithKey,
map,
reduce,
values,
groupBy,
props,
join
} = R;
const debts = [{
amount: 10,
debtor: "Mark",
creditor: "John"
},
{
amount: 20,
debtor: "Mark",
creditor: "John"
},
{
amount: 10,
debtor: "Mark",
creditor: "Tom"
}
];
const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));
const process =
pipe(
groupBy(groupKey),
map(reduce(mergeAmount, {})),
values);
console.log(process(debts));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
Идея состоит в том, чтобы разделить процесс на три этапа:
- Группировать должников и кредиторов вместе
- Для каждой группы должников / кредиторов объединить сумму
- Извлечь каждую группу должников / кредиторов в массив
Шаг 1: groupBy (groupKey)
Шаг 1 получает исходный debts
массив
{
"Mark ~> John": [
{
amount: 10,
creditor: "John",
debtor: "Mark"
},
{
amount: 20,
creditor: "John",
debtor: "Mark"
}
],
"Mark ~> Tom": [
{
amount: 10,
creditor: "Tom",
debtor: "Mark"
}
]
}
Шаг 2: карта (уменьшение (mergeAmount, {}))
Шаг 2 получает выходные данныес шага 1
{
"Mark ~> John": {
amount: 30,
creditor: "John",
debtor: "Mark"
},
"Mark ~> Tom": {
amount: 10,
creditor: "Tom",
debtor: "Mark"
}
}
Шаг 3: значения
Шаг 3 получает выходные данные с шага 2
[
{
amount: 30,
creditor: "John",
debtor: "Mark"
},
{
amount: 10,
creditor: "Tom",
debtor: "Mark"
}
]