请问一下我的英语和写作问题,我有一组json数据,我试图将其制成嵌套树状结构,但未获得成功,希望有人能帮助我。 我的示例数据:
[ {
"id" : 1,
"name" : "Abc",
"path" : "/",
"type" : "folder"
}, {
"id" : 2,
"name" : "Xyz",
"path" : "/Abc/",
"type" : "folder"
}, {
"id" : 3,
"name" : "Pqr",
"path" : "/Abc/Xyz/",
"type" : "folder"
}, {
"id" : 4,
"name" : "Zap",
"path" : "/Abc/Xyz/Pqr/",
"type" : "folder"
},{
"id" : 5,
"name" : "file1",
"path" : "/Abc/Xyz/Pqr/",
"type" : "file"
},{
"id" : 6,
"name" : "file2",
"path" : "/Abc/Xyz/Pqr/",
"type" : "file"
},{
"id" : 7,
"name" : "file3",
"path" : "/Abc/Xyz/",
"type" : "file"
},{
"id" : 8,
"name" : "file4",
"path" : "/Abc/Xyz/Pqr/Zap/",
"type" : "file"
}
抱歉,我需要少量的大数据才能正确理解,现在我想要的嵌套格式就是这样。
[{
"id" : 1,
"name" : "Abc",
"path" : "/",
"type" : "folder"
"Children":[{
"id" : 2,
"name" : "Xyz",
"path" : "/Abc/",
"type" : "folder",
"Children":[{
"id" : 3,
"name" : "Pqr",
"path" : "/Abc/Xyz/",
"type" : "folder",
"Children": [{
"id" : 4,
"name" : "Zap",
"path" : "/Abc/Xyz/Pqr/",
"type" : "folder",
"Children":[{
"id" : 8,
"name" : "file4",
"path" : "/Abc/Xyz/Pqr/Zap/",
"type" : "file"
}]
},{
"id" : 5,
"name" : "file1",
"path" : "/Abc/Xyz/Pqr/",
"type" : "file"
},{
"id" : 6,
"name" : "file2",
"path" : "/Abc/Xyz/Pqr/",
"type" : "file"
}]
},{
"id" : 7,
"name" : "file3",
"path" : "/Abc/Xyz/",
"type" : "file"
}]
}]
}
现在与lodash一起使用的登录如下:datas = allData
const dd= [];
_.forEach(datas, function(v, k) {
let cc = {};
if (v.type == 'folder') {
cc['children'] = _.filter(datas, function(v1, k1) {
if (v.path + v.name + '/' == v1.path || v1.path.startsWith(v.path + v.name + '/')) {
return v1;
}
});
cc['name'] = v.name;
cc['type'] = v.type;
cc['id'] = v.id;
cc['path'] = v.path;
dd.push(cc);
} else {
if (v.path == '/') {
dd.push(cc);
}
}
});
但是得不到正确的答案,我知道问题已经太久了,但是请帮我解决这个问题。
答案 0 :(得分:2)
哇!很好玩。
const data = [ {
"id" : 1,
"name" : "Abc",
"path" : "/",
"type" : "folder"
}, {
"id" : 2,
"name" : "Xyz",
"path" : "/Abc/",
"type" : "folder"
}, {
"id" : 3,
"name" : "Pqr",
"path" : "/Abc/Xyz/",
"type" : "folder"
}, {
"id" : 4,
"name" : "Zap",
"path" : "/Abc/Xyz/Pqr/",
"type" : "folder"
},{
"id" : 5,
"name" : "file1",
"path" : "/Abc/Xyz/Pqr/",
"type" : "file"
},{
"id" : 6,
"name" : "file2",
"path" : "/Abc/Xyz/Pqr/",
"type" : "file"
},{
"id" : 7,
"name" : "file3",
"path" : "/Abc/Xyz/",
"type" : "file"
},{
"id" : 8,
"name" : "file4",
"path" : "/Abc/Xyz/Pqr/Zap/",
"type" : "file"
}]
const pathPartRegex = /.*?\//g;
const tree = _.reduce(data, (result, value) => {
const pathParts = value.path.match(pathPartRegex);
let node = result;
let path = "";
// Go down through tree until last path part
const notLastPart = pathParts.splice(0, pathParts.length - 1);
for (const pathPart of notLastPart) {
path += pathPart;
const existingNode = node.children
? node.children.find(item => item.path === path)
: node.find(item => item.path === path);
if (existingNode) {
node = existingNode
} else {
// If we need to traverse over a path that doesn't exist, just create it
// See notes
const newNode = {
path: path,
children: []
};
// The root element is just an array, and doesn't have a children property
if (node.children) {
node.children.push(newNode);
} else {
node.push(newNode);
}
node = newNode;
}
}
// Add new node
const newNode = {
id: value.id,
name: value.name,
type: value.type,
path: value.path,
children: []
};
// The root element is just an array, and doesn't have a children property
if (node.children) {
node.children.push(newNode);
} else {
node.push(newNode);
}
return result;
}, []);
通过RunKit(https://npm.runkit.com/lodash)进行了测试
注意:
样本数据集没有涵盖如何处理根本没有定义“父”路径的情况:
const data = [{
"id" : 1,
"name" : "Abc",
"path" : "/",
"type" : "folder"
}, {
"id" : 3,
"name" : "Pqr",
"path" : "/Abc/Xyz/",
"type" : "folder"
}];
在子级之后也没有定义“父级”路径的情况:
const data = [{
"id" : 1,
"name" : "Abc",
"path" : "/",
"type" : "folder"
}, {
"id" : 3,
"name" : "Pqr",
"path" : "/Abc/Xyz/",
"type" : "folder"
}, {
"id" : 2,
"name" : "Xyz",
"path" : "/Abc/",
"type" : "folder"
}];
我编写的代码将处理这些问题,但可能会创建没有id
属性的节点。如果需要处理这种情况,则可以预先修复输入数据,也可以修改此代码以处理这些情况。
答案 1 :(得分:0)
我也正在努力的答案是这样的:
const sts=_.memoize(function(){ return []; });
const result = _.filter(folderdata, function(item){
let parentName = '';
if(item.path != '/')parentName = item.path;
item.children = sts(item.path+item.name+'/');
if (item.type == 'folder') return !(parentName && sts(parentName).push(item));
});