Reputation: 1063
I have the array of objects
[
{ id: 1, parent_id: null, title: 'Title 1' },
{ id: 2, parent_id: 1, title: 'Title2' },
{ id: 3, parent_id: 2, title: 'Title 3' },
{ id: 4, parent_id: null, title: 'Title 4' }
]
I need to transform this array to this
[
{
id: 1,
parent_id: null,
children: [
{
id: 2,
parent_id: 1,
title: 'Title2',
children: [
{ id: 3, parent_id: 2, title: "Title 3" }
]
}
]
},
{id: 4, parent_id: null, title: 'Title 4' }
]
I have no idea, how can do this
Upvotes: 0
Views: 53
Reputation: 2392
Try with this recursion:
function update(item) {
if (item.parent_id) {
const parent = arr.findIndex(p => p.id === item.parent_id);
if (!arr[parent].children)
arr[parent].children = [];
const index = arr[parent].children.findIndex(ch => ch.id === item.id);
if (index >= 0)
arr[parent].children.splice(index, 1);
arr[parent].children.push(item);
update(arr[parent]);
}
}
arr.forEach(item => update(item));
arr = arr.filter(item => !item.parent_id);
console.log(arr);
Upvotes: 0
Reputation: 386578
You could take a standard approach for generating a tree from data with id and parent id.
var data = [{ id: 1, parent_id: null, title: 'Title 1' }, { id: 2, parent_id: 1, title: 'Title2' }, { id: 3, parent_id: 2, title: 'Title 3' }, { id: 4, parent_id: null, title: 'Title 4' }],
tree = function (data, root) {
var t = {};
data.forEach(o => {
Object.assign(t[o.id] = t[o.id] || {}, o);
t[o.parent_id] = t[o.parent_id] || {};
t[o.parent_id].children = t[o.parent_id].children || [];
t[o.parent_id].children.push(t[o.id]);
});
return t[root].children;
}(data, null);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 4272
I think this will work:
const original = [
{ id: 1, parent_id: null, title: 'Title 1' },
{ id: 2, parent_id: 1, title: 'Title2' },
{ id: 3, parent_id: 2, title: 'Title 3' },
{ id: 4, parent_id: null, title: 'Title 4' }
]
const transform = arr => {
for (let i = arr.length - 1; i >= 0; i--) {
const post = arr[i]
const parent = arr.find(p => p.id === post.parent_id)
if (parent) {
if (!parent.children) {
parent.children = []
}
parent.children.push(post)
post.duplicate = true
}
}
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i].duplicate) {
arr.splice(i, 1)
}
}
return arr
}
console.log(transform(original))
Here is the fiddle: https://jsfiddle.net/7h8mj63e/
Upvotes: 1