我正在尝试合并list
数组中的项目,以便在结果数组中仅存在唯一的date
字段。我还需要结果数组中的amount
项字段是原始数组中共享相同date
值的所有项的总和。
我的list
数组中的数据格式如下:
var list = [
{amount: "10", date: "2000-03-01"},// These three records have same date
{amount: "20", date: "2000-03-01"},// field, need to combine into
{amount: "30", date: "2000-03-01"},// one record
{amount: "50", date: "2000-03-03"},
{amount: "100", date: "2000-03-05"},
{amount: "30", date: "2000-03-06"},// These two records have same date
{amount: "70", date: "2000-03-06"},// field, need to combine
{amount: "80", date: "2000-03-10"},
]
我需要将上面的列表转换为此:
var expectedList = [
{amount: "60", date: "2000-03-01"}, // combined item
{amount: "50", date: "2000-03-03"},
{amount: "100", date: "2000-03-05"},
{amount: "100", date: "2000-03-06"},// combined item
{amount: "80", date: "2000-03-10"},
]
答案 0 :(得分:4)
一个解决方案可能是通过Array.reduce()
进行,其中您将首先构建一个中间映射,该映射将date
键映射到总计amount
个值。然后,您可以通过Object.entries()
将映射转换回平面数组,如下所示:
var list = [
{amount: "10", date: "2000-03-01"},
{amount: "20", date: "2000-03-01"},
{amount: "30", date: "2000-03-01"},
{amount: "50", date: "2000-03-03"},
{amount: "100", date: "2000-03-05"},
]
const result = Object.entries(list.reduce((mapping, item) => {
/* During each iteration of reduce over the list, retrieve
the totalled "amount" for this item's "date" */
mapping[ item.date ] = mapping[ item.date ] || 0
/* Increment the "total" for this "date" by the "amount" of
the current item, and persist into the map */
mapping[ item.date ] += Number.parseInt(item.amount)
return mapping
}, {})).map(([amount, date]) => {
/* Object.entries() returns a list of key/value pairs from the
mapping created by our reduce() step. Here we transform each
key/value pair of the mapping back to the desired format */
return { amount, date }
});
console.log(result)
答案 1 :(得分:2)
您可以使用reduce函数来实现。
list.reduce(( prev, curr )=>{
// parse string amount into number for calculation
curr.amount = parseInt(curr.amount);
let index;
if ((index = prev.findIndex( item => item.date == curr.date )) > -1 )
prev[index].amount += curr.amount;
else
prev.push( curr );
return prev;
}, []);
输出:
[ { amount: 60, date: '2000-03-01' },
{ amount: 50, date: '2000-03-03' },
{ amount: 100, date: '2000-03-05' } ]
答案 2 :(得分:2)
如果您想要简单易懂的代码,请使用下面的代码段。
下面的代码基本上遍历列表,然后遍历输出以检查两个元素中的日期是否相同。如果是这样,它将添加金额并将found
的值设置为true。在.forEach()
的末尾,如果found
仍然为false(如果我们没有找到日期匹配的元素),则将值推入输出数组。
var list = [
{amount: "10", date: "2000-03-01"},
{amount: "20", date: "2000-03-01"},
{amount: "30", date: "2000-03-01"},
{amount: "50", date: "2000-03-03"},
{amount: "100", date: "2000-03-05"},
]
var output = [];
var found = false;
list.forEach(e1 => {
found = false;
output.forEach(e2 => {
if (e1.date == e2.date) {
e2.amount = parseInt(e2.amount) + parseInt(e1.amount);
found = true;
}
});
if (!found) {
output.push(e1);
}
});
console.log(output);
答案 3 :(得分:2)
似乎是一个相当简单的两步过程。首先,将数组简化为日期与金额总和的映射,然后将该映射的值转换为新的数组。
var list = [
{amount: "10", date: "2000-03-01"},
{amount: "20", date: "2000-03-01"},
{amount: "30", date: "2000-03-01"},
{amount: "50", date: "2000-03-03"},
{amount: "100", date: "2000-03-05"}
]
const expectedList = Array.from(list.reduce((map, {amount, date}) => {
return map.set(date, (map.get(date) || 0) + parseInt(amount))
}, new Map())).map(([date, amount]) => ({ amount, date }))
console.info(expectedList)
答案 4 :(得分:1)
var list = [
{amount: "10", date: "2000-03-01"},
{amount: "20", date: "2000-03-01"},
{amount: "30", date: "2000-03-01"},
{amount: "50", date: "2000-03-03"},
{amount: "100", date: "2000-03-05"},
]
const builtObject = list.reduce((acc, {date, amount}) => {
acc[date] = acc[date] || 0
acc[date] += parseInt(amount)
return acc
}, {})
const rs = Object.entries(builtObject).map(([date, amount]) => ({amount, date}))
console.log(rs)