I always struggle when faced with this problem, and it takes some serious work. I am currently trying to solve this problem and it will probably take me a few days. Wanted to see if you have a system or simple way of solving this problem.
Basically, say you have a flat list of DOM nodes with padding left indentation at steps of 15px. Visually, it forms a tree like a file browser. But structurally in the DOM, it is implemented as a flat list. How can you then iterate through the list and build a tree?
<div style='padding-left: 0px'>A</div>
<div style='padding-left: 15px'>AA</div>
<div style='padding-left: 15px'>AB</div>
<div style='padding-left: 30px'>ABA</div>
<div style='padding-left: 30px'>ABB</div>
<div style='padding-left: 45px'>ABBA</div>
<div style='padding-left: 45px'>ABBB</div>
<div style='padding-left: 45px'>ABBC</div>
<div style='padding-left: 30px'>ABC</div>
<div style='padding-left: 15px'>AC</div>
<div style='padding-left: 0px'>B</div>
<div style='padding-left: 0px'>C</div>
...
That should then become a JSON tree like this:
[
{
title: 'A',
children: [
{
title: 'AA',
children: []
},
{
title: 'AB',
children: [
{
title: 'ABA',
children: []
},
{
title: 'ABB',
children: [
{
title: 'ABBA',
children: []
},
{
title: 'ABBB',
children: []
},
{
title: 'ABBC',
children: []
}
]
},
{
title: 'ABC',
children: []
}
]
},
{
title: 'AC'
}
]
},
{
title: 'B',
children: []
},
{
title: 'C',
children: []
}
]
How do you do this? I get lost:
let tree = []
let path = [0]
let items = list('div')
items.forEach(item => {
let left = parseInt(item.style[`padding-left`] || 0) % 15
let set = tree
let p = path.concat()
while (left) {
let x = p.shift()
set[x] = set[x] || { children: [] }
set = set[x].children
left--
}
})
function list(s) {
return Array.prototype.slice.call(document.querySelectorAll(s))
}