I have this starting array:
const data = [
{
roles: [
{
name: "one",
},
{
name: "two",
},
],
name: "Alfa",
},
{
roles: [
{
name: "three",
},
],
name: "Bravo",
},
{
name: "Charlie",
},
];
I need to create an object for every name. If a name has more than one role, one item for name.
So, with the example, I need this array:
[
{ name: "Alfa", role: "one" },
{ name: "Alfa", role: "two" },
{ name: "Bravo", role: "three" },
{ name: "Charlie" }
];
This is the function that I wrote:
const cleanRoles = (data) => {
const roles = data.map((person) => {
if (Array.isArray(person.roles) && person.roles.length > 0) {
return person.roles.map((role) => {
return {
name: person.name,
role: role.name,
};
});
}
return {
name: person.name,
};
});
return roles;
};
But I get
[
[
{ name: "Alfa", role: "one" },
{ name: "Alfa", role: "two" },
],
[{ name: "Bravo", role: "three" }],
{ name: "Charlie" },
];
How can I refactor my function to get what I need?
5
Answers
flatMap
does whatmap
does, but expects arrays as return values and concatenates those together into 1 large array as output:Shorter versions
Reduce the data with mapping roles to new array items. Avoid
.flatMap()
since it’s slower than reducing:A generic solution with any number of properties:
a reduce, a forEach, and easy to read code… (right?)
If you swap around the
name
androles
properties in each object and write it out more uniformly, you could make much more sense of what’s going on. I rearranged your data structure below to make the data appear easier to read.You could simplify this to the following: Map each item in the array to an object with a
name
and arole
(only if the item hasroles
).