var str = '[{"name":"a","description":"a","type":"string","son":[1]},{"name":"b","description":"b","son":[2],"type":"string"},{"name":"c","description":"v","son":[],"type":"string"},{"name":"d","description":"d","son":[],"type":"string"}]';
var values = JSON.parse(str);
var value = {};
values.forEach((item)=>{
get(item,value);
})
function get(item,obj){
if(item.son.length != 0){
item.son.forEach((j)=>{
obj[item.name] = {};
get(values[j],obj[item.name]);
})
}else{
obj[item.name] = {};
value = Object.assign(value,obj);
}
}
values.forEach((item)=>{
if(item.son.length != 0){
item.son.forEach((j)=>{
delete value[values[j].name];
})
}
})
console.log(value)
如上代码,大致意思就是将这个 json 转为对象,然后根据 name 生成新的对象,代码没问题,运行一下就知道了,需要简化下,感觉写的很 low
1
blackywkl 2017-08-08 16:52:48 +08:00
用 map 或 reduce 吧
|
2
fulvaz 2017-08-08 17:04:30 +08:00
|
3
jmc891205 2017-08-08 17:11:00 +08:00
你用递归来做的话 树的高度很大的时候会爆栈的吧
|
4
yeze322 2017-08-08 17:41:19 +08:00
|
5
shuson 2017-08-08 17:43:25 +08:00
读不懂题
|
6
vincenth520 OP @yeze322 是,如果键不同级重复的话是写不进去的。。。
|
7
vincenth520 OP @shuson 你运行一下你就应该知道是什么意思
|
8
vincenth520 OP @fulvaz 修改全局变量没啥大问题吧。。。
|
9
fulvaz 2017-08-08 18:05:22 +08:00
@vincenth520 额,问题挺大,尽可能写无副作用代码。
|
10
seki 2017-08-08 18:06:56 +08:00
感觉你需要 lodash
|
11
8qwe24657913 2017-08-08 18:47:49 +08:00 1
https://gist.github.com/8qwe24657913/e5f42dde7d279ce1534528b4570f9cfc#file-v2ex_381395-js
读楼主的代码比重写都难……写了两种,第二种和楼主代码行为一样 第一种与第二种的区别: 循环引用 [{"name":"a","son":[0]}] 第二种爆栈 对象唯一 [{"name":"a","son":[2]},{"name":"b","son":[2]},{"name":"c","son":[]}] 第二种 result.a.c !== result.b.c 需要哪种自取…… |
12
broker 2017-08-08 19:51:19 +08:00 1
首先理清思路,拆分出几个函数,这样便于理解和测试,后面再进行优化~
按理解写了一下,不过没有测试正确性~ var str = '[{"name":"a","description":"a","type":"string","son":[1]},{"name":"b","description":"b","son":[2],"type":"string"},{"name":"c","description":"v","son":[],"type":"string"},{"name":"d","description":"d","son":[],"type":"string"}]'; var values = []; try { values = JSON.parse(str); } catch(ex) { console.err(ex); } var value = {}; function getChildrenByIndex(index) { var children = []; var i = 0; for (i = 0; i < values[index].son.length; i++) { children.push(values[values[index].son[i]]); } return children; } function getRoots(values) { var i = 0; var ii = 0; var roots = []; var isRoot; for (i = 0; i < values.length; i++) { isRoot = true; for (ii = 0; ii < values.length; ii++) { if (i !== ii) { if (values[ii].son.indexOf(i) !== -1) { isRoot = false; } } } if(isRoot) { roots.push(values[i]); } } return roots; } function getNodeNameByIndex(index) { return values[index].name; } function rebuild(roots) { var i = 0; var ii = 0; var res = {}; for (i = 0; i < roots.length; i++) { res[roots[i].name] = {}; for(ii = 0; ii < roots[i].son.length; ii++) { res[roots[i].name][getNodeNameByIndex(roots[i].son[ii])] = rebuild(getChildrenByIndex(roots[i].son[ii])); } } return res; } var roots = getRoots(values); console.log(rebuild(roots)); |
13
vincenth520 OP @8qwe24657913 虽然不是很能懂,但先感谢大神,自己逻辑思维有点差。。。
|
14
vincenth520 OP @broker 先感谢,再慢慢理解。。。
|
15
piku 2017-08-09 21:50:59 +08:00 via Android
我觉得问题在于你把 JSON 转成 obj 后,obj 要怎么拿去用。如果 json 的项目是一定的( item.name 可控),直接定义变量来存储岂不更省事
|
16
vincenth520 OP @piku 肯定不能直接定义 obj 了,不然也就不会这样做了
|
17
piku 2017-08-10 22:04:27 +08:00 via Android
我觉得结合上下文,应该有更好的实现方法或逻辑或算法。做这样复杂的嵌套调用,不太好
|