Reputation: 632
I have the following array tree in javascript:
[
{
"id": 1,
"parentId": null,
"description": "Item 1",
"value": 0,
"children": [
{
"id": 2,
"parentId": 1,
"description": "Item 1.1",
"value": 0,
"children": [
{
"id": 3,
"parentId": 2,
"description": "Item 1.1.1",
"value": 0,
"children": []
}
]
}
]
},
{
"id": 4,
"parentId": null,
"description": "Item 2",
"value": 0,
"children": [
{
"id":5,
"parentId": 4,
"description": "Item 2.1",
"value": 0,
"children": []
}
]
}
]
I want to turn it into a flat one with it's levels, like this (see level attribute):
[
{
"id":1,
"parentId": null,
"description":"Item 1",
"value":0,
"level": "1"
},
{
"id":2,
"parentId": 1,
"description":"Item 1.1",
"value":0,
"level": "1.1"
},
{
"id":3,
"parentId": 2,
"description":"Item 1.1.1",
"value":0,
"level": "1.1.1"
},
{
"id":4,
"parentId": null,
"description":"Item 2",
"value":0,
"level": "2"
},
{
"id":5,
"parentId": 4,
"description":"Item 2.1",
"value":0,
"level": "2.1"
}
]
What's the best way to do this regardless of depth?
PS: I have the flat one too, but without "level" attribute and the proposal is to add this attribute based on parentId and sort list by it, like following:
Item 1
Item 1.1
Item 1.1.1
Item 2
Item 2.1
Upvotes: 0
Views: 333
Reputation: 753
If you don't want to limit the solution by the depth of the array, then I suggest not to use recursion.
const solution = data => {
const stack = data.map((item, index) => ({ ...item, level: `${index + 1}` }))
const result = []
while (stack.length) {
const item = stack.pop()
const { children, ...restItem } = item
stack.push(...item.children.map((child, index) => ({ ...child, level: `${item.level}.${index + 1}` })))
result.push(restItem)
}
return result
}
const data = [
{
"id": 1,
"parentId": null,
"description": "Item 1",
"value": 0,
"children": [
{
"id": 2,
"parentId": 1,
"description": "Item 1.1",
"value": 0,
"children": [
{
"id": 3,
"parentId": 2,
"description": "Item 1.1.1",
"value": 0,
"children": []
}
]
}
]
},
{
"id": 4,
"parentId": null,
"description": "Item 2",
"value": 0,
"children": [
{
"id":5,
"parentId": 4,
"description": "Item 2.1",
"value": 0,
"children": []
}
]
}
]
console.log(solution(data))
Upvotes: 1
Reputation: 5766
If you recursively loop through your array (assuming that children
will always be the key), something like this will work.
const arr = [
{
"id": 1,
"parentId": null,
"description": "Item 1",
"value": 0,
"children": [
{
"id": 2,
"parentId": 1,
"description": "Item 1.1",
"value": 0,
"children": [
{
"id": 3,
"parentId": 2,
"description": "Item 1.1.1",
"value": 0,
"children": []
}
]
}
]
},
{
"id": 4,
"parentId": null,
"description": "Item 2",
"value": 0,
"children": [
{
"id":5,
"parentId": 4,
"description": "Item 2.1",
"value": 0,
"children": []
}
]
}
]
const newArray = [];
const flatten = (item, parentIdx) => {
// separate parent from children
item.forEach(({ children, ...child}, idx) => {
// create level
const level = `${parentIdx ? `${parentIdx}.` : ''}${idx + 1}`;
// add parent to new array
newArray.push({...child, level});
// recursively flatten children
flatten(children, level);
})
}
flatten(arr)
console.log(newArray)
Upvotes: 0