I have this Array
[
{
id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc",
description: "Response #1",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
responses: [
{
id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007",
description: "Response #2",
media: "b414e44f-7371-4cef-b0d9-d240e55b0ed1.jpg",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
}
]
},
{
id: "d8271620-9937-4815-bd35-acad62d85f53",
description: "Response #3",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
responses: [
{
id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca",
description: "Response #4",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
}
]
}
]
And I want to rename the properties to
[
{
id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc",
name: "User — Response #1",
children: [
{
id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007",
name: "User — Response #2"
}
]
},
{
id: "d8271620-9937-4815-bd35-acad62d85f53",
name: "User — Response #3",
children: [
{
id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca",
name: "User — Response #4",
}
]
}
]
I've tried to solve this with map and recursion
function mapArray(array) {
return array.map(({ id, description, user: { name }, responses }) => {
if (responses !== undefined) {
return mapArray(responses);
}
return {
id,
name: `${name} — ${description}`,
children: responses
};
});
}
But it the array becomes nested and the children is undefined.
[
[
{
id: '69442cb1-7de7-4f2d-9c8b-d6689fa1d007',
name: 'User — Response #2',
children: undefined
}
],
[
{
id: '05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca',
name: 'User — Response #4',
children: undefined
}
]
]
Please note that the responses have indefinite depth.
Where did I mess up? Thanks
You are very close. Only 1 line change inside the if conditions should fix it.
function mapArray(array) {
return array.map(({ id, description, user: { name }, responses }) => {
if (responses !== undefined) {
responses = mapArray(responses);
}
return {
id,
name: `${name} — ${description}`,
children: responses
};
});
}
Samridh diagnosed the issue and gave you a useful fix. If you're looking for a slightly more declarative version of the same idea, you could write the function like this:
const mapArray = (array) => array .map (
({id, description, user: {name}, responses}) => ({
id,
name: `${name} - ${description}`,
...(responses ? {children: mapArray (responses)} : {})
})
)
const input = [{id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc", description: "Response #1", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}, responses: [{id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007", description: "Response #2", media: "b414e44f-7371-4cef-b0d9-d240e55b0ed1.jpg", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}}]}, {id: "d8271620-9937-4815-bd35-acad62d85f53", description: "Response #3", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}, responses: [{id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca", description: "Response #4", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}}]}]
console .log (mapArray (input))
.as-console-wrapper {max-height: 100% !important; top: 0}
Might me a little ugly but is an alternate.
Also Array.map() returns an array so it is obvious for it to be nested.
var obj = [
{
id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc",
description: "Response #1",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
responses: [
{
id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007",
description: "Response #2",
media: "b414e44f-7371-4cef-b0d9-d240e55b0ed1.jpg",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
}
]
},
{
id: "d8271620-9937-4815-bd35-acad62d85f53",
description: "Response #3",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
responses: [
{
id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca",
description: "Response #4",
user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
}
]
}
];
var newObj = [];
obj.forEach(({ id, description: name, user: children }) => {
newObj.push({ id, name, children: [children] });
});
console.log(JSON.stringify(newObj, null, 2));
.as-console-wrapper {
max-height: 100% !important;
}