继上一题的一个反向算法
https://segmentfault.com/q/10...源数据
[
"浙江,宁波,鄞州区",
"浙江,宁波,江北区",
"浙江,杭州,富阳",
"浙江,杭州,上城区",
"上海,黄浦区"
]
目标结构
const data = [
{
city:'浙江',
children:[
{
city:'宁波',
children:[{
city:'鄞州区',
children:[]
},{
city:'江北区',
children:[]
}]
},
{
city:'杭州',
children:[{
city:'富阳',
children:[]
},{
city:'上城区',
children:[]
}]
}
]
},
{
city:'上海',
children:[
{
city:'黄浦区',
children:[]
}
]
}
]
这次不需要递归,只需要两层循环。
先来一个一般思路的解法:
这里
map
是建立一个路径(Key)到对象的映射,方便直接找到节点,在其下添加子节点。这里的root
为了和节点结构一样,不是给的多根数组,直接给的节点模形。不过这个解法里,拼
path
和parentKey
有点繁琐。如果不用 map,而是每出现一个 Key 就直接按顺序去当前节点中找指定 Key 的节点,或者(如果不存在时)创建此节点的话,就会简化不少了,毕竟拆分字符串之后的 Key 都是有顺序的,不同于一般按路径查找节点的情况。修改过后:
当前父节点
parent
其实不是一个父节点,而是引用的父节点的children
,毕竟都是对children
进行操作。改过后的这段代码,主要逻辑在第二个
forEach()
中,就是在parent
里查找指定city
的节点,如果没找到就创建一个加进去。Array.prototype.push
返回新数组的长度,所以它的返回值 - 1
就是新添加的节点的索引。改成这样了,再稍微改一下,用
reduce
就是一句话了或者重新给代码排个版(仅改变了排版),下面这个是我比较喜欢的风格,层次结构比较清楚