先看一段数据结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| const list = [ { id: 1, name: 'Node1', children: [ { id: 3, name: 'Node1_1', children: [ { id: 8, name: 'Node1_1_1' }, { id: 9, name: 'Node1_1_2' }, { id: 10, name: 'Node1_1_3' }] }, { id: 4, name: 'Node1_2' }, { id: 5, name: 'Node1_3' }] }, { id: 2, name: 'Node2', children: [ { id: 6, name: 'Node2_1' }, { id: 7, name: 'Node2_2' }] } ]
|
以上的数据结构是一个典型的树形结构,数组里面的每一项可能都会有 children 这个属性,然后 children 里面的每一项又是一个 list。
需求
通过传入任何一个 id 来找到所有的 parents 节点。
假如说我们传入的 id 是 8 那么它的 parentIds 就是[1, 3]
思路
- 定义一个空对象
const map = {}
- 定义一个函数,传入循环的 list 和当前层级的 parentIds
- 循环这个 list 在每一项中
map[item.id] = parentIds
- 假如该 item有 children 这个属性的话,就继续递归这个 children 然后把当前层级的 parents 和 prevParents 进行合并,用于下一次递归。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function findParentsById(list, id) { const map = {}; function findParents(data, prevParents = []) { if (Array.isArray(data) && data.length) { data.forEach(item => { const parents = []; map[item.id] = prevParents; if (Array.isArray(item.children)) { parents.push(item.id) findParents(item.children, [...prevParents, ...parents]) } }) } } findParents(list); return map[id]; }
|