javascript - 尾递归 JSON 构造函数

标签 javascript json node.js recursion tail-recursion

我有一个来自 NPM 包 'directory-tree 的目录结构' 我想将其展平为一个更简单的嵌套结构。我想要一个尾递归解决方案来将第一个对象转换为第二个对象,但我无法思考如何构造它。

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

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

{
  "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));

关于javascript - 尾递归 JSON 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48266446/

相关文章:

node.js - Express.js- 添加响应主体

javascript - 如何理解Nodejs、SPA、API的关系?

javascript - 如何在页面加载时删除具有空属性的元素

javascript - Ember 计算等于不适用于 ember-mirage

php - 我如何从网络上获取 YouTube 视频 ID?

ios - 如何使用for循环在Objective C中向NSArray添加值或添加对象?

javascript - 客户端将 EDN 转换为 JSON(HTML5 应用程序使用的数据)

javascript - 获取第一个 td 文本以删除本地存储数组中的项目

javascript - 嵌套 json 传入 ajax 调用

javascript - 在 Mongoose 数据库中生成唯一的随机数而不重复?