一道前端算法题
这道题目是我面试的时候遇见的一道题目. 当时写的并不好, 回来后做了深入思考. 但是没啥思路. 然后我在 segmentfault 和 v2ex 上提问了一下. 先在这里感谢各位网友的热心回答. 感觉他们真的好聪明又热心. 从他们的回答中我感觉学到了不少. 我会把问题地址放在最后. 先在这里对这道题目做下总结
题目如下:
给一个数据结构如下
var data = [ { "name": "手机", "childs": [ { "name": "iPhone", "childs": [ {"name": "iPhone X"}, {"name": "iPhone XR"}, {"name": "iPhone XS"}, ] }, { "name": "HUAWEI", "childs": [ {"name": "HUAWEI Mate 20"}, {"name": "HUAWEI Mate 20 X"}, {"name": "HUAWEI Mate 20 Pro"}, ] } ] } ];
然后让封装一个函数, 根据名称得到其遍历的路径. 例如参数是 HUAWEI Mate 20. 那么函数返回 手机 / HUAWEI/HUAWEI Mate 20. 要求函数可以适用多层的数据结构, 例如上面的数据只有三层深度, 如果扩展为 10 层的话函数仍然可以适用.
解答:
基本这道题有两个思路
第一个是在递归过程中摒弃不需要的, 把匹配的路径留下来, 代码如下, 其实这种思路下可以写出多种代码
function findPhone(name, node, path ) { const newPath = path + '/' + node.name; if (node.name != name) { if (node.childs) { for (let item of node.childs) { const result = findPhone(name, item, newPath) if(result) { return result; } } return false; } else { return false; } } else { return newPath; } } findPhone('iPhone X', data[0], '');
第二种是把结构压扁, 然后用对象的方式来取. 这种方式还是蛮有优势的, 我们只需要把树遍历一遍就可以得到一个压扁的结构, 这样用就很方便. 代码如下
function getPathByName(data,objName){ var conf = {}; function getConf(_data,_path){ for(var i in _data){ var __path = _path? _path + "/"+_data[i].name:_data[i].name; conf[_data[i].name] = __path; if(_data[i].childs){ getConf(_data[i].childs,__path); } } } getConf(data,""); return conf[objName]; } alert(getPathByName(data,"HUAWEI Mate 20 Pro"));
问题回答地址 :
https://segmentfault.com/q/1010000019243581
https://www.v2ex.com/t/566080#reply28