我有一个来自NPM包'directory-tree‘的目录结构,我想把它扁平化成一个更简单的嵌套结构。我想要一个尾部递归解决方案来将第一个对象转换为第二个对象,但我在如何构造它方面遇到了麻烦。
当然,主要条件是第一个结构中的'node‘是'file’还是'directory‘。如果它是一个文件,我们只需要文件的基本名称作为相对路径的关键字。但是,如果它是一个目录,我们希望该目录的基名成为一个对象的关键字,并从那里向下递归。
我将使用他们的示例来说明其结构:
{
"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"
}
}
}
}
发布于 2018-01-16 19:53:03
对于您的情况,我们可以将深度优先搜索转换为尾递归。
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));
发布于 2018-01-16 00:03:19
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;
}这是一个简单的递归方法,这不是尾部调用递归,因为它是非常困难(=不值得)遍历一棵树只有一个尾部调用。
发布于 2018-01-16 00:08:54
您可以通过检查类型来采用递归方法。
对于'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; }
https://stackoverflow.com/questions/48266446
复制相似问题