根据嵌套数组重新组合对象数组
Regroup array of objects based on nested array
我有一个对象数组。每个对象都包含另一个内部数组。我想将每个内部数组作为外部对象,并将剩余的旧外部元素作为新创建的外部对象的子属性。
输入
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] }))],
[]
);
创建一个索引爱好的对象。当遍历人时,创建一个带有 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
对于这种事情可以说是 not the right tool to use,但是如果你想使用它:
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);
您可以减少数组并为结果集查找同名项。
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()
teamed up with Array.prototype.forEach()
to loop over the list of hobbies
, together with destructuring assignment 语法可以轻松解决问题:
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%;}
使用 Array#reduce
。您可以像这样 {hobbies,...b}
使用 Spread operator 在每次迭代中传递对象
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))
我有一个对象数组。每个对象都包含另一个内部数组。我想将每个内部数组作为外部对象,并将剩余的旧外部元素作为新创建的外部对象的子属性。
输入
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] }))],
[]
);
创建一个索引爱好的对象。当遍历人时,创建一个带有 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
对于这种事情可以说是 not the right tool to use,但是如果你想使用它:
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);
您可以减少数组并为结果集查找同名项。
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()
teamed up with Array.prototype.forEach()
to loop over the list of hobbies
, together with destructuring assignment 语法可以轻松解决问题:
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%;}
使用 Array#reduce
。您可以像这样 {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))