将值重复推送到新数组中



我有这样的对象数组

const data = [
{ 
name: "John",
transaction: "10/10/2010",
item: "Bag"
},
{ 
name: "Steven",
transaction: "31/10/2020",
item: "Shoe"
},
{ 
name: "John",
transaction: "18/06/2019",
item: "Sock"
}
]

您可以看到该数组中对象的名称具有重复的名称但不同的事务

然后我想要这样的结果:

const result = [
{ 
name: "John",
transactions: [
{
date: "10/10/2010",
item: "Bag"
},
{
date: "18/06/2019",
item: "Sock"
}        
]
},
{ 
name: "Steven",
transactions: [
{
date: "31/10/2020",
item: "Shoe"
}  
]
},
]

因此,新数组重新整理了同一个人的新事务

其代码为:

const data = [
{ 
name: "John",
transaction: "10/10/2010",
item: "Bag"
},
{ 
name: "Steven",
transaction: "31/10/2020",
item: "Shoe"
},
{ 
name: "John",
transaction: "18/06/2019",
item: "Sock"
}
]
let Transactions = []
data.forEach(data => {
Transactions.some(t => {
if(t.name === data.name){
t.transactions.push({date:data.transaction,item:data.item})
return;
}
})
Transactions.push({
name:data.name,
transactions:[
{date:data.transaction,item:data.item}
]
})
console.log(Transactions);
})

array.some 比 forEach 循环更好,我 think.so 决定坚持下去。

请尝试以下示例

const data = [
{
name: "John",
transaction: "10/10/2010",
item: "Bag",
},
{
name: "Steven",
transaction: "31/10/2020",
item: "Shoe",
},
{
name: "John",
transaction: "18/06/2019",
item: "Sock",
},
];
const output = data.reduce((previousValue, { name, transaction, item }) => {
const index = previousValue.findIndex((entry) => entry.name === name);
if (index === -1) {
previousValue = [
...previousValue,
{
name: name,
transactions: [{ date: transaction, item }],
},
];
} else {
previousValue[index].transactions = previousValue[
index
].transactions.concat({
date: transaction,
item,
});
}
return previousValue;
}, []);
console.dir(output, { depth: null, color: true });

  • Array.prototype.reduce((
  • Array.prototype.concat((
  • Array.prototype.findIndex((

一个简单的reduce就可以做到这一点

const data = 
[ { name: 'John',   transaction: '10/10/2010', item: 'Bag'  } 
, { name: 'Steven', transaction: '31/10/2020', item: 'Shoe' } 
, { name: 'John',   transaction: '18/06/2019', item: 'Sock' } 
] 

const result = data.reduce((a,{name,transaction:date,item})=>
{
let x = a.find(e=>e.name===name)
if (!x) 
{
let n = a.push({name, transactions:[]}) -1
x = a[n]         
}
x.transactions.push({date,item})
return a
},[])
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

较短的版本

const result = data.reduce((a,{name,transaction:date,item})=>
{
let x = a.find(e=>e.name===name) || (a[a.push({name, transactions:[]}) -1])       
x.transactions.push({date,item})
return a
},[])

您可以以一种功能性的方式做到这一点以使其可读,下面的工作解决方案是使用ramdajs

const data = [
{
name: 'John',
transaction: '10/10/2010',
item: 'Bag'
},
{
name: 'Steven',
transaction: '31/10/2020',
item: 'Shoe'
},
{
name: 'John',
transaction: '18/06/2019',
item: 'Sock'
}
]
const result = pipe(
groupBy(obj => obj.name),
mapObjIndexed((groupObjs, groupName) => ({
name: groupName,
transactions: map(
groupObj => ({
date: groupObj.transaction,
item: groupObj.item
}),
groupObjs
)
})),
values
)(data)
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script>const { groupBy, mapObjIndexed, pipe, map, values } = R</script>

这是 ramdajs 文档的链接

使用 lodash 的_.groupBy()函数怎么样?

const data = [
{ 
name: "John",
transaction: "10/10/2010",
item: "Bag",
},
{ 
name: "Steven",
transaction: "31/10/2020",
item: "Shoe",
},
{ 
name: "John",
transaction: "18/06/2019",
item: "Sock",
}
]
const result = _.groupBy(data, "name")
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>