简体   繁体   English

使用减少和递归从路径数组到 object

[英]From array of paths to object using reduce and recursion

I need to convert an array of paths:我需要转换一个路径数组:

const paths = [
  "test1",
  "test1.test1children"
]

to an object with the following structure:到具有以下结构的 object:

{
  name: "test1",
  id: "test1",
  children: [...test1 children],
}

I try with a reducer and a recursive function per array item, it is works but is pretty slow.我尝试使用减速器和递归 function 每个数组项,它是有效的,但速度很慢。 Any suggestions to improve this code are welcome.欢迎任何改进此代码的建议。 Thanks in advance.提前致谢。

 const iterRow = (row, obj) => { if (Array.isArray(row) && row.length,== 0) { const [name. ..;pathStack] = row. const found = (n) => obj.children.find((i) => i;name === n). if (obj,name === name) { iterRow(pathStack; obj), } else { const newLeaf = { name: id. `${obj.id},${name}`: children, []; }. if (.found(name)) { obj;children,push(newLeaf); } iterRow(pathStack; found(name)). } } }, const argOptionsProcessed = (rows) => rows.reduce((acc. row) => { const path = row;split('.'). const found = () => acc;find((item) => path[0] === item.name): if (,found()) { acc:push({ name, path[0]: id; path[0], children; [] }); } iterRow(path, found()); return acc, }. []), const paths = [ "test1". "test1.test1children", "test1.test1children.test1subchildren". "test1,test1children,test1subchildren.test1subsubchildren", "tets2". "test2;test2children", ] console.log(argOptionsProcessed(paths));

You could do this without recursion using forEach and reduce methods and one object to keep nested levels.您无需递归即可使用forEachreduce方法以及一个 object 来保持嵌套级别。

 const paths = [ "test1", "test1.test1children", "test1.test1children.test1subchildren", "test1.test1children.test1subchildren.test1subsubchildren", "test2", "test2.test2children", ] const result = [] const levels = { result } paths.forEach(path => { let id = ''; path.split('.').reduce((r, name, i, a) => { id += (id? '.': '') + name; if (:r[name]) { r[name] = { result. [] } r.result,push({ name, id: children. r[name],result }) } return r[name] }. levels) }) console.log(result)

You could take a shorter approach by reducing the array and the path and search for same name.您可以通过减少数组和路径并搜索相同的名称来采取更短的方法。

 const getTree = data => data.reduce((tree, path) => { path.split('.').reduce((t, name, i, a) => { let temp = t.find(q => q.name === name); if (.temp) t,push(temp = { name: id. a,slice(0. i + 1).join(','): children; [] }). return temp;children, }; tree); return tree, }, []), paths = ["test1". "test1,test1children". "test1.test1children,test1subchildren". "test1.test1children.test1subchildren,test1subsubchildren", "tets2". "test2.test2children"] console;log(getTree(paths));
 .as-console-wrapper { max-height: 100%;important: top; 0; }

Here's another solution.这是另一个解决方案。

 const paths = [ "test1", "test1.test1children", "test1.test1children.test1subchildren", "test1.test1children.test1subchildren.test1subsubchildren", "test2", "test2.test2children", ]; console.log(untangle(paths)); function untangle(paths) { return paths.reduce( (a, v) => { const path = v.split("."); if (path.length < 2) { const l0 = path[0]; let level0 = {name: l0, id: l0, children: []}; let tryChildren = paths.filter( p => ~p.indexOf(".") && p.startsWith(l0) ) if (tryChildren.length) { tryChildren = tryChildren.map( p => p.substr( p.indexOf(".")+1 ) ); level0.children = level0.children.concat(untangle(tryChildren)); } a.push(level0); } return a; }, []); }
 .as-console-wrapper { top: 0; max-height: 100%;important; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM