如何将文件夹结构JSON String转换为JS Array。我遵循JSON字符串
[{ "Name": "A", "ParentName": "Config", "Type": "default" },
{ "Name": "SubA", "ParentName": "A", "Type": "default" },
{ "Name": "SubAFile", "ParentName": "SubA", "Type": "file" },
{ "Name": "B", "ParentName": "Config", "Type": "default" },
{ "Name": "C", "ParentName": "Config", "Type": "default" }]
我想以下列格式制作JS Array对象
var NewStr = [{
"name": 'A',
"id": 'A',
"icon": 'fa fa-folder',
"items": [{
"title": "A",
"icon": "fa fa-folder",
"id": "A",
"items": [{
"name": "subA",
"icon": "fa fa-folder",
"id": "subA",
"items": [{
"title": "SubA",
"icon": "fa fa-folder",
"id": "SubA",
"items": [{
"name": "SubAFile",
"icon": "fa fa-file"
}]
}]
}]
}]
}, {
"name": 'B',
"id": 'b',
"icon": "fa fa-folder"
}, {
"name": 'C',
"id": 'C',
"icon": "fa fa-folder"
}];
注意:我已经包含了ParentName来识别文件夹结构的层次结构。 ID与名称相同。
对此有何建议?
谢谢..
答案 0 :(得分:1)
首先使用JSON.parse
从有效的JSON字符串生成obbject。
JSON.parse()
方法解析JSON字符串,构造字符串描述的JavaScript值或对象。可以提供可选的reviver函数,以在返回结果对象之前对其执行转换。
然后,您可以使用迭代方法生成一个树,创建一个具有引用插入或引用的父对象的所需属性的新对象,使用临时对象。
这也适用于未排序和嵌套的项目。
var data = [{ Name: "A", ParentName: "Config", Type: "default" }, { Name: "SubA", ParentName: "A", Type: "default" }, { Name: "SubAFile", ParentName: "SubA", Type: "file" }, { Name: "B", ParentName: "Config", Type: "default" }, { Name: "C", ParentName: "Config", Type: "default" }],
tree = function (data, root) {
var r = [], o = {};
data.forEach(function (a) {
var temp = { name: a.Name, icon: a.Type === 'file' ? 'fa fa-file' : 'fa fa-folder' };
if (o[a.Name] && o[a.Name].items) {
temp.items = o[a.Name].items;
}
o[a.Name] = temp;
if (a.ParentName === root) {
r.push(temp);
} else {
o[a.ParentName] = o[a.ParentName] || {};
o[a.ParentName].items = o[a.ParentName].items || [];
o[a.ParentName].items.push(temp);
}
});
return r;
}(data, 'Config');
console.log(tree);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)
这么棒的测验!我保证会在几个小时内找到解决方案。你给的是一种“反向二叉树”,就BigO来说,目前的解决方案看起来太难看了。
如果您不介意我会发布草稿preSolution并继续考虑更多正确的方法来提高工作效率并稍后进行编辑。
var tree = {}
function findParent(data, parentName){
var parentExist = false;
$.each(data, function(index, value){
parentExist = (value.name == parentName);
if(parentExist){
moveChild(data, index, tree, tree[value.parentName]);
} else {
createParent(parentName, tree);
}
}
}
function moveChild(collectionIn, child, collectionOut, parent){
collectionOut[parent].push(collectionIn[child]);
splice(collectionIn[child], 1);
}
function createParent(parentName, targetTree);
$.each(data, function(index, val){
findParent(index.parentName);
});
提示我要检查:
答案 2 :(得分:0)
您可以使用Map
按名称键入节点,并在使用reduce
迭代输入时构建树。对于每个节点,如果父节点尚不存在,则创建父节点。发生这种情况时,请记住这个新创建的父项作为树的根:它的子项是您要生成的数组。
这是ES6代码:
// Sample input JSON parsed:
const items = JSON.parse('[{"Name":"A","ParentName":"Config","Type":"default"},{"Name":"new","ParentName":"A","Type":"file"},{"Name":"B","ParentName":"Config","Type":"default"},{"Name":"C","ParentName":"Config","Type":"default"}]');
const arr = items.reduce( ([nodes, root], {Name, ParentName, Type}) => {
const node = Object.assign({ // create node
name: Name,
icon: Type == 'default' ? 'fa fa-folder' : 'fa fa-file'
}, nodes.get(Name)); // add previously registered children, if any
const parent = nodes.get(ParentName) || (root = {}); // create parent if not present
parent.items = (parent.items || []).concat(node); // add current as child
return [nodes.set(Name, node).set(ParentName, parent), root];
}, [new Map, {}] )[1].items; // start with empty map, return the items of the root
// Output result
console.log(arr);

.as-console-wrapper { max-height: 100% !important; top: 0; }

在您的问题更新中,所需的输出已更改,具有更多嵌套级别:具有子级的节点现在需要一个中间对象作为子级(具有大多数相同的属性),而子级节点又连接到其自己的{{ 1}}属性。
以下是适用于此目的的ES6代码:
items

function buildTree(folders) {
const [nodes, root] = folders.reduce( ([nodes, root], {Name, ParentName, Type}) => {
const node = Object.assign({ // create node
name: Name,
id: Name,
icon: Type == 'default' ? 'fa fa-folder' : 'fa fa-file'
}, nodes.get(Name)); // add previously registered children, if any
const parent = nodes.get(ParentName) || (root = {}); // create parent if not present
parent.items = (parent.items || []).concat(node); // add current as child
return [nodes.set(Name, node).set(ParentName, parent), root];
}, [new Map, {}] );
// To add the extra intermediate levels (requested in updated question):
nodes.forEach( node => {
if (node.items) node.items = [{
title: node.name,
icon: node.icon,
id: node.id,
items: node.items
}]
});
return root.items[0].items;
}
// Sample JSON data, parsed
const folders = JSON.parse('[{ "Name": "A", "ParentName": "Config", "Type": "default" },{ "Name": "SubA", "ParentName": "A", "Type": "default" },{ "Name": "SubAFile", "ParentName": "SubA", "Type": "file" },{ "Name": "B", "ParentName": "Config", "Type": "default" },{ "Name": "C", "ParentName": "Config", "Type": "default" }]');
const arr = buildTree(folders);
// Output result
console.log(arr);

对于支持ES6很少的浏览器(如IE):
.as-console-wrapper { max-height: 100% !important; top: 0; }

function buildTree(folders) {
var result = folders.reduce(function (acc, obj) {
var nodes = acc[0];
var root = acc[1];
var node = { // create node
name: obj.Name,
id: obj.Name,
icon: obj.Type == 'default' ? 'fa fa-folder' : 'fa fa-file'
};
// add previously registered children, if any
if (nodes[obj.Name]) node.items = nodes[obj.Name].items;
var parent = nodes[obj.ParentName] || (root = {}); // create parent if not present
parent.items = (parent.items || []).concat(node); // add current as child
nodes[obj.Name] = node;
nodes[obj.ParentName] = parent;
return [nodes, root];
}, [{}, {}] );
// To add the extra intermediate levels (requested in updated question):
for (var name in result[0]) {
var node = result[0][name];
if (node.items) node.items = [{
title: node.name,
icon: node.icon,
id: node.id,
items: node.items
}];
}
return result[1].items[0].items;
}
// Sample JSON data, parsed
var folders = JSON.parse('[{ "Name": "A", "ParentName": "Config", "Type": "default" },{ "Name": "SubA", "ParentName": "A", "Type": "default" },{ "Name": "SubAFile", "ParentName": "SubA", "Type": "file" },{ "Name": "B", "ParentName": "Config", "Type": "default" },{ "Name": "C", "ParentName": "Config", "Type": "default" }]');
var arr = buildTree(folders);
// Output result
console.log(arr);