今天看到了一道题:
已知数据格式,实现一个函数 fn 找出链条中所有的父级 id
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
| const list = [{ id: '1', name: 'test1', children: [ { id: '11', name: 'test11', children: [ { id: '111', name: 'test111' }, { id: '112', name: 'test112' } ]
}, { id: '12', name: 'test12', children: [ { id: '121', name: 'test121' }, { id: '122', name: 'test122' } ] } ] }]; const id = '112' const fn = (value) => { ... } fn(id, list)
|
先给出答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function fn(id, list){ var res = [] function dfs(list, temp = []){ for(const node of list){ if(node.id === id){ res = temp.concat(node.id) return } else if(node.children){ dfs(node.children, temp.concat(node.id)) } } } dfs(list) return res }
|
而我最开始的解法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function fn(id, list){ var res = [] function dfs(list, temp = []){ for(const node of list){ if(node.id === id){ temp.push(node.id) res = temp return } else if(node.children){ temp.push(node.id) dfs(node.children, temp) } } } dfs(list) return res }
|
然而这个解法得不到正确答案
这是由于 Array.push()
会改变自身的数组,而Array.concat()
不会改变自身的数组。在正确解法中,使用concat
方法去传参,并不会影响自身数组,因此在回溯时,得到的还是未被错误路径污染的数组。而用push
方法,会改变自身的数组,因此回溯时数组已经被污染了,而且temp
的后续修改也会影响到res
。
Array.push()
和Array.concat()
区别
- concat不会改变自身数组
- push会改变自身数组
- 在push中传入一个数组,该数组会成为原数组的一个元素。
- push方法返回的是新数组的长度
- concat返回新数组