繁体   English   中英

尾递归JSON构造函数

[英]Tail recursive JSON constructor

我有一个NPM包' directory-tree '的目录结构,我想把它压缩成一个更简单的嵌套结构。 我想要一个尾递归解决方案将第一个对象转换为第二个对象,但是我无法绕过如何构造它。

当然,主要条件是第一个结构中的“节点”是“文件”还是“目录”。 如果它是一个文件,我们只需要文件的基本名称来键入相对路径。 但是,如果它是一个目录,我们希望目录的基本名称键入一个对象并在那里递归。

我将用他们的例子来说明结构:

 { "path": "photos", "name": "photos", "size": 600, "type": "directory", "children": [ { "path": "photos/summer", "name": "summer", "size": 400, "type": "directory", "children": [ { "path": "photos/summer/june", "name": "june", "size": 400, "type": "directory", "children": [ { "path": "photos/summer/june/windsurf.jpg", "name": "windsurf.jpg", "size": 400, "type": "file", "extension": ".jpg" } ] } ] }, { "path": "photos/winter", "name": "winter", "size": 200, "type": "directory", "children": [ { "path": "photos/winter/january", "name": "january", "size": 200, "type": "directory", "children": [ { "path": "photos/winter/january/ski.png", "name": "ski.png", "size": 100, "type": "file", "extension": ".png" }, { "path": "photos/winter/january/snowboard.jpg", "name": "snowboard.jpg", "size": 100, "type": "file", "extension": ".jpg" } ] } ] } ] } 

我希望最终的结构更加简单。 类似于以下内容:

 { "photos": { "summer": { "june": { "windsurf.jpg": "photos/summer/june/windsurf.jpg" } }, "winter": { "january": { "ski.png": "photos/winter/january/ski.png", "snowboard.jpg": "photos/winter/january/snowboard.jpg" } } } } 

我们可以为您的案例将深度优先搜索转换为尾递归。

 let testObj = { "path": "photos", "name": "photos", "size": 600, "type": "directory", "children": [ { "path": "photos/summer", "name": "summer", "size": 400, "type": "directory", "children": [ { "path": "photos/summer/june", "name": "june", "size": 400, "type": "directory", "children": [ { "path": "photos/summer/june/windsurf.jpg", "name": "windsurf.jpg", "size": 400, "type": "file", "extension": ".jpg" } ] } ] }, { "path": "photos/winter", "name": "winter", "size": 200, "type": "directory", "children": [ { "path": "photos/winter/january", "name": "january", "size": 200, "type": "directory", "children": [ { "path": "photos/winter/january/ski.png", "name": "ski.png", "size": 100, "type": "file", "extension": ".png" }, { "path": "photos/winter/january/snowboard.jpg", "name": "snowboard.jpg", "size": 100, "type": "file", "extension": ".jpg" } ] } ] } ] }; function tailRecurse(stack, result){ if (!stack.length) return result; // stack will contain // the next object to examine [obj, ref] = stack.pop(); if (obj.type == 'file'){ ref[obj.name] = obj.path; } else if (obj.type == 'directory'){ ref[obj.name] = {}; for (let child of obj.children) stack.push([child, ref[obj.name]]); } return tailRecurse(stack, result); } // Initialise let _result = {}; let _stack = [[testObj, _result]]; console.log(tailRecurse(_stack, _result)); 

function copyNode(node, result = {}){
   if(node.type === "directory"){
      const folder = result[node.name] = {};
      for(const sub of node.children)
           copyNode(sub, folder);

  } else {
      result[node.name] = node.path;
  }
  return result;
}

这是一种简单的递归方法,这不是尾调用递归,因为仅使用一个尾调用遍历树是非常困难的(=不值得)。

你可以通过chekcing类型采取递归方法。

对于'directory'取一个对象并迭代子节点。

否则,使用给定名称指定密钥的路径。

 function fn(source, target) { if (source.type === 'directory') { target[source.name] = {}; (source.children || []).forEach(o => fn(o, target[source.name])); } else { target[source.name] = source.path; } } var source = { path: "photos", name: "photos", size: 600, type: "directory", children: [{ path: "photos/summer", name: "summer", size: 400, type: "directory", children: [{ path: "photos/summer/june", name: "june", size: 400, type: "directory", children: [{ path: "photos/summer/june/windsurf.jpg", name: "windsurf.jpg", size: 400, type: "file", extension: ".jpg" }] }] }, { path: "photos/winter", name: "winter", size: 200, type: "directory", children: [{ path: "photos/winter/january", name: "january", size: 200, type: "directory", children: [{ path: "photos/winter/january/ski.png", name: "ski.png", size: 100, type: "file", extension: ".png" }, { path: "photos/winter/january/snowboard.jpg", name: "snowboard.jpg", size: 100, type: "file", extension: ".jpg" }] }] }] }, target = {}; fn(source, target); console.log(target); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

暂无
暂无

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

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