我正在尝试使用.reduce方法来计算不同Expense对象的金额。这些Expenses可以是不同类型的,我想保持数组中的对象被它分割。例如,以下一系列费用:
[
{type: A, amount: 2},
{type: A, amount: 1},
{type: B, amount: 2},
{type: A, amount: 3},
{type: C, amount: 2},
{type: B, amount: 1}
]
应该变成这样:
[
{type: A, amount: 6},
{type: B, amount: 3},
{type: C, amount: 2}
]
还要注意,如果不存在该类型的费用,则不应存在金额:0,而应减去一笔费用。因此,如果没有C类费用,结果应该是:
[
{type: A, amount: 6},
{type: B, amount: 3}
]
这就是我所走的路:
private joinExpenses(expenses: Expense[]): Expense[] {
// Add all expenses amount splitted by payment type and store in object
const expenseArrayAsObject = expenses.reduce(
(expensesObject, item) => {
const type = item.type;
if (!expensesObject.hasOwnProperty(type)) {
expensesObject[type] = {
type: type,
amount: {
amount: 0
} as Money
} as Expense;
}
const expense: Expense = expensesObject[type];
expense.amount.amount = expense.amount.amount + item.amount.amount;
expensesObject[type] = expense;
return expensesObject;
},
{} as { [key: string]: any }
);
// Convert object to array
const joinedExpenses: Expense[] = [];
for (const key in expenseArrayAsObject) {
joinedExpenses.push(expenseArrayAsObject[key]);
}
return joinedExpenses;
}
这是可行的,但我觉得首先映射到对象并将其转换为数组是一个太多的步骤,而且可以简化。之后我可以进行一些操作,但我觉得我在数组中迭代太多了。。我就是不知道怎么做。你能帮我吗?
您可以将以下内容与.reduce()
和.find()
组合使用:
const data = [
{type: 'A', amount: 2},
{type: 'A', amount: 1},
{type: 'B', amount: 2},
{type: 'A', amount: 3},
{type: 'C', amount: 2},
{type: 'B', amount: 1}
];
const result = data.reduce((a, c) => {
const found = a.find(e => e.type === c.type);
if (found) found.amount = found.amount + c.amount;
return found ? a : a.concat(c);
}, []);
console.log(result);
这就是您需要的吗?
const array = [
{type: 'A', amount: 2},
{type: 'A', amount: 1},
{type: 'B', amount: 2},
{type: 'A', amount: 3},
{type: 'C', amount: 2},
{type: 'B', amount: 1}
];
const result = array.reduce((acc, item) => {
const current = acc.find(el => el.type === item.type);
if(!current) {
acc.push(item)
}else{
current.amount += item.amount;
}
return acc;
}, []);
console.log(result);
在reduce
回调中,使用findIndex
检查累加器accray中是否存在具有相同键的对象。然后更新金额的值,否则创建对象
let data = [{
type: 'A',
amount: 2
},
{
type: 'A',
amount: 1
},
{
type: 'B',
amount: 2
},
{
type: 'A',
amount: 3
},
{
type: 'C',
amount: 2
},
{
type: 'B',
amount: 1
}
]
let newData = data.reduce((acc, curr) => {
let ifKeyExist = acc.findIndex((item) => {
return item.type === curr.type;
});
if (ifKeyExist === -1) {
acc.push({
type: curr.type,
amount: curr.amount
});
} else {
acc[ifKeyExist].amount += curr.amount;
}
return acc;
}, []);
console.log(newData)
reduce
使用对象作为累加器。使用type
作为键,并为其分配新对象。然后使用Object.values
获取所需的输出。
const data = [
{type: 'A', amount: 2},
{type: 'A', amount: 1},
{type: 'B', amount: 2},
{type: 'A', amount: 3},
{type: 'C', amount: 2},
{type: 'B', amount: 1}
];
const out = Object.values(data.reduce((acc, { type, amount }) => {
// If type doesn't exist as a key on the accumulator
// add it and set its value to a new object
acc[type] = acc[type] || { type, amount: 0 };
// Increment the object amount value
acc[type].amount += amount;
// Return the accumulator
return acc;
}, {}));
console.log(out);