这道题目是我面试的时候遇见的一道题目. 当时写的并不好, 回来后做了深入思考. 但是没啥思路. 然后我在 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
来源:https://www.cnblogs.com/cgdx/p/10907960.html