admin 管理员组文章数量: 1086019
Given an array like this:
[
{ id: 1, emailAddresses: ["[email protected]", "[email protected]"] },
{ id: 2, emailAddresses: ["[email protected]" },
{ id: 3, emailAddresses: ["[email protected]", "[email protected]", "[email protected]"]
]
How could I use Javascript to reduce this to an array like this:
[
{ id: 1, emailAddress: "[email protected]" },
{ id: 1, emailAddress: "[email protected]" },
{ id: 2, emailAddress: "[email protected]" },
{ id: 3, emailAddress: "[email protected]" },
{ id: 3, emailAddress: "[email protected]" },
{ id: 3, emailAddress: "[email protected]" }
]
I've read about the functions reduce
, flat
, map
and so on and read lots of the questions on SO about using them but I can't find anything that's asking quite the same as this and I can't get my head around using those functions to do it.
Given an array like this:
[
{ id: 1, emailAddresses: ["[email protected]", "[email protected]"] },
{ id: 2, emailAddresses: ["[email protected]" },
{ id: 3, emailAddresses: ["[email protected]", "[email protected]", "[email protected]"]
]
How could I use Javascript to reduce this to an array like this:
[
{ id: 1, emailAddress: "[email protected]" },
{ id: 1, emailAddress: "[email protected]" },
{ id: 2, emailAddress: "[email protected]" },
{ id: 3, emailAddress: "[email protected]" },
{ id: 3, emailAddress: "[email protected]" },
{ id: 3, emailAddress: "[email protected]" }
]
I've read about the functions reduce
, flat
, map
and so on and read lots of the questions on SO about using them but I can't find anything that's asking quite the same as this and I can't get my head around using those functions to do it.
5 Answers
Reset to default 3You could use flatMap
const input = [
{ id: 1, emailAddresses: ["[email protected]", "[email protected]"] },
{ id: 2, emailAddresses: ["[email protected]"] },
{ id: 3, emailAddresses: ["[email protected]", "[email protected]", "[email protected]"] }
]
const output = input.flatMap(o =>
o.emailAddresses.map(e => ({ id: o.id, emailAddress: e }) )
)
console.log(output)
If flatMap
is not supported, you could use a nested for...of
loop:
const input = [{id:1,emailAddresses:["[email protected]","[email protected]"]},{id:2,emailAddresses:["[email protected]"]},{id:3,emailAddresses:["[email protected]","[email protected]","[email protected]"]}];
const output = []
for (const { id, emailAddresses } of input)
for (const emailAddress of emailAddresses)
output.push({ id, emailAddress })
console.log(output)
You can map over your data and then use reduce to flatten the resulting array:
const result = data
.map(datum => {
return datum.emailAddresses.map(emailAddress => {
return { id: datum.id, emailAddress };
});
})
.reduce((result, current) => {
return [...result, ...current];
}, []);
We can use Array.prototype.reduce
to go over each object in the array and take into consideration the multiple values in the emailAddress
property array and create separate object for each one and finally accumulate the new objects in the new array (r
):
const data = [
{ id: 1, emailAddresses: ["[email protected]", "[email protected]"] },
{ id: 2, emailAddresses: ["[email protected]"] },
{ id: 3, emailAddresses: ["[email protected]", "[email protected]", "[email protected]"]}
]
const flat = data.reduce((r, e) => {
e.emailAddresses.forEach((obj) => r.push({id: e.id, emailAddresses : obj }));
return r;
}, []);
console.log(flat);
You can use reduce and map
const data = [
{ id: 1, emailAddresses: ["[email protected]", "[email protected]"] },
{ id: 2, emailAddresses: ["[email protected]"] },
{ id: 3, emailAddresses: ["[email protected]", "[email protected]", "[email protected]"]}
]
const flat = (toFlatten) =>
toFlatten.reduce((r,c)=> {
r.push(...c.emailAddresses.map(email=>({id: c.id, emailAddress: email})))
return r
}, [])
console.log(flat(data))
Here is a solution that doesn't use any array prototype but does, instead, take advantage of function generators.
The script below iterates the array, acquire all keys of the element except emailAddresses
, which is handled separately, and for each email address it yields an object filled with the single email address and the rest of the data.
This solution iterate the original array only once.
Because it uses function generators, this solution is widely supported, it just won't work on IE due it's lack of support for function generators, despite babel or TSC can easily add patibility to that.
const input = [
{ id: 1, emailAddresses: ["[email protected]", "[email protected]"] },
{ id: 2, emailAddresses: ["[email protected]"] },
{ id: 3, emailAddresses: ["[email protected]", "[email protected]", "[email protected]"] }
];
function* flattenEmailAddresses(arr) {
for (var {emailAddresses, ...keys} of arr) {
for (var emailAddress of emailAddresses) yield {...keys, emailAddress};
}
}
console.log([...flattenEmailAddresses(input)]);
本文标签: Flatten nested array with key value pairs in JavascriptStack Overflow
版权声明:本文标题:Flatten nested array with key value pairs in Javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744078948a2529877.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论