我有一个对象数组。每个对象都包含另一个内部数组。我想将每个内部数组作为外部对象,并将剩余的旧外部元素作为新创建的外部对象的子属性。
输入
data = [
{
name: "Sam",
ssn: 123,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }]
},
{
name: "John",
ssn: 234,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }]
},
{
name: "Mathew",
ssn: 345,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }, {name: "carroms"}]
}
];
预期输出
[
{
name: "cricket",
person_details: [
{ name: "Sam", ssn: 123, age: 25 },
{ name: "John", ssn: 234, age: 25 },
{ name: "Mathew", ssn: 345, age: 25 }
]
},
{
name: "football",
person_details: [
{ name: "Sam", ssn: 123, age: 25 },
{ name: "John", ssn: 234, age: 25 },
{ name: "Mathew", ssn: 345, age: 25 }
]
},
{
name: "carroms",
person_details: [
{ name: "Mathew", ssn: 345, age: 25 }
]
}
]
我尝试使用Reduce的内容如下
this.data = this.data.reduce(
(a, x) => [...x.hobbies.map(h => ({ ...x, hobbies: [h] }))],
[]
);
您可以减少数组并为结果集查找相同名称的项。
var data = [{ name: "Sam", ssn: 123, age: 25, hobbies: [{ name: "cricket" }, { name: "football" }] }, { name: "John", ssn: 234, age: 25, hobbies: [{ name: "cricket" }, { name: "football" }] }, { name: "Mathew", ssn: 345, age: 25, hobbies: [{ name: "cricket" }, { name: "football" }, { name: "carroms" }] }],
result = data.reduce((r, { hobbies, ...o }) => {
hobbies.forEach(({ name }) => {
var group = r.find(q => q.name === name);
if (!group) r.push(group = { name, person_details: [] });
group.person_details.push(o);
})
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
简单的Array.prototype.reduce()
与Array.prototype.forEach()
一起循环hobbies
的列表,再加上析构函数赋值语法,可以很容易地完成任务:
const data = [{name:"Sam",ssn:123,age:25,hobbies:[{name:"cricket"},{name:"football"}]},{name:"John",ssn:234,age:25,hobbies:[{name:"cricket"},{name:"football"}]},{name:"Mathew",ssn:345,age:25,hobbies:[{name:"cricket"},{name:"football"},{name:"carroms"}]}],
result = data.reduce((r,{hobbies, ...userData}) => (
hobbies.forEach(({name}) => (
match = r.find(({hobby}) => hobby == name),
match ?
match['person_details'].push({...userData}) :
r.push({hobby:name, person_details: [{...userData}]})
))
, r), [])
console.log(result)
.as-console-wrapper{min-height:100%;}
创建一个为爱好编制索引的对象。当迭代人员时,如果还不存在name
和person_details
数组,则创建一个新对象,然后推送到person_details
数组:
const data = [
{
name: "Sam",
ssn: 123,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }]
},
{
name: "John",
ssn: 234,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }]
},
{
name: "Mathew",
ssn: 345,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }, {name: "carroms"}]
}
];
const peopleByHobbies = {};
for (const { hobbies, ...personData } of data) {
for (const { name } of hobbies) {
if (!peopleByHobbies[name]) peopleByHobbies[name] = { name, person_details: [] };
peopleByHobbies[name].person_details.push({ ...personData });
}
}
const output = Object.values(peopleByHobbies);
console.log(output);
reduce
可以说不是用于这类事情的合适工具,但如果你想使用它:
const data = [
{
name: "Sam",
ssn: 123,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }]
},
{
name: "John",
ssn: 234,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }]
},
{
name: "Mathew",
ssn: 345,
age: 25,
hobbies: [{ name: "cricket" }, { name: "football" }, {name: "carroms"}]
}
];
const peopleByHobbies = data.reduce((peopleByHobbies, { hobbies, ...personData }) => {
for (const { name } of hobbies) {
if (!peopleByHobbies[name]) peopleByHobbies[name] = { name, person_details: [] };
peopleByHobbies[name].person_details.push({ ...personData });
}
return peopleByHobbies;
}, {});
const output = Object.values(peopleByHobbies);
console.log(output);
使用Array#reduce
。您可以在每次迭代中使用Spread运算符传递对象,如{hobbies,...b}
const arr = [{ name: "Sam", ssn: 123, age: 25, hobbies: [{ name: "cricket" }, { name: "football" }] }, { name: "John", ssn: 234, age: 25, hobbies: [{ name: "cricket" }, { name: "football" }] }, { name: "Mathew", ssn: 345, age: 25, hobbies: [{ name: "cricket" }, { name: "football" }, { name: "carroms" }] } ];
const res = arr.reduce((acc, {hobbies,...b}) => {
hobbies.forEach(i => {
acc[i.name] = acc[i.name] || {
name: i.name,
persional_details: []
};
acc[i.name].persional_details.push(b)
})
return acc
}, {});
console.log(Object.values(res))