Javascript 从绝对文件路径构建JSON对象
我(在我的angularjs应用程序中)从服务器收到一个目录列表,如下所示:Javascript 从绝对文件路径构建JSON对象,javascript,json,Javascript,Json,我(在我的angularjs应用程序中)从服务器收到一个目录列表,如下所示: ['.trash-user', 'cats', 'cats/css', 'cats/images/blog', 'cats/images/gallery'] [{ label: '.trash-user'}, {label: 'cats', children: [{ label: 'css'}, {label: 'images', children: [{ label: 'bl
['.trash-user',
'cats',
'cats/css',
'cats/images/blog',
'cats/images/gallery']
[{
label: '.trash-user'},
{label: 'cats',
children: [{
label: 'css'},
{label: 'images',
children: [{
label: 'blog'},
{label: 'gallery'}
]}
]}
}]
我想构建一个javascript变量,如下所示:
['.trash-user',
'cats',
'cats/css',
'cats/images/blog',
'cats/images/gallery']
[{
label: '.trash-user'},
{label: 'cats',
children: [{
label: 'css'},
{label: 'images',
children: [{
label: 'blog'},
{label: 'gallery'}
]}
]}
}]
路径是按随机顺序排列的
希望有人有一些真正优雅的解决方案,但任何解决方案都是值得赞赏的
编辑:
这是我天真的方法,我在递归方面遇到了真正的麻烦。
我只能使0级工作:
var generateTree = function(filetree){
console.log('--------- filetree -------');
var model = [];
var paths = [];
for(var i=0;i<filetree.length;i++) {
paths = filetree[i].split('/');
for(var j=0;j<paths.length;++j) {
var property = false;
for(var k=0;k<model.length;++k) {
if (model[k].hasOwnProperty('label') &&
model[k].label === paths[0]) {
property = true;
}
}
if (!property) {
model.push({label: paths[0]});
}
}
}
console.log(model);
};
var generateTree=函数(文件树){
log('------------filetree-------');
var模型=[];
var路径=[];
对于(var i=0;i这样的东西应该可以工作:
function pathsToObject(paths) {
var result = [ ];
// Iterate through the original list, spliting up each path
// and passing it to our recursive processing function
paths.forEach(function(path) {
path = path.split('/');
buildFromSegments(result, path);
});
return result;
// Processes each path recursively, one segment at a time
function buildFromSegments(scope, pathSegments) {
// Remove the first segment from the path
var current = pathSegments.shift();
// See if that segment already exists in the current scope
var found = findInScope(scope, current);
// If we did not find a match, create the new object for
// this path segment
if (! found) {
scope.push(found = {
label: current
});
}
// If there are still path segments left, we need to create
// a children array (if we haven't already) and recurse further
if (pathSegments.length) {
found.children = found.children || [ ];
buildFromSegments(found.children, pathSegments);
}
}
// Attempts to find a ptah segment in the current scope
function findInScope(scope, find) {
for (var i = 0; i < scope.length; i++) {
if (scope[i].label === find) {
return scope[i];
}
}
}
}
函数路径对象(路径){
var结果=[];
//遍历原始列表,拆分每个路径
//并将其传递给递归处理函数
forEach(函数(路径){
path=path.split('/');
buildFromSegments(结果、路径);
});
返回结果;
//以递归方式处理每条路径,每次处理一段
函数buildFromSegments(范围、路径段){
//从路径中删除第一段
var current=pathSegments.shift();
//查看当前范围中是否已存在该段
var found=findInScope(范围,当前);
//如果未找到匹配项,请为创建新对象
//此路径段
如果(!找到){
作用域。推送(找到={
标签:当前
});
}
//如果还剩下路径段,我们需要创建
//子数组(如果我们还没有)并进一步递归
if(路径段长度){
found.children=found.children | |[];
buildFromSegments(found.children,pathSegments);
}
}
//尝试在当前作用域中查找ptah段
函数findInScope(作用域,查找){
对于(变量i=0;i
如果您想要优雅的解决方案,让我们从更优雅的输出开始:
{
'.trash-user': {},
'cats': {
'css': {},
'images': {
'blog': {},
'gallery': {},
},
},
}
在存储唯一密钥方面,对象比数组好得多,速度也快得多(顺序1而不是顺序n)。要获得上述输出,请执行以下操作:
var obj = {};
src.forEach(p => p.split('/').reduce((o,name) => o[name] = o[name] || {}, obj));
var convert = obj => Object.keys(obj).map(key => Object.keys(obj[key]).length?
{ label: key, children: convert(obj[key]) } : { label: key });
var arr = convert(obj);
或者在ES6之前的JavaScript中:
var obj = {};
src.forEach(function(p) {
return p.split('/').reduce(function(o,name) {
return o[name] = o[name] || {};
}, obj);
});
function convert(obj) {
return Object.keys(obj).map(function(key) {
return Object.keys(obj[key]).length?
{ label: key, children: convert(obj[key])} : { label: key };
});
}
var arr = convert(obj);
现在,您有了一个自然对象树,可以轻松地映射到您想要的任何对象。要获得所需的输出,请执行以下操作:
var obj = {};
src.forEach(p => p.split('/').reduce((o,name) => o[name] = o[name] || {}, obj));
var convert = obj => Object.keys(obj).map(key => Object.keys(obj[key]).length?
{ label: key, children: convert(obj[key]) } : { label: key });
var arr = convert(obj);
或者在ES6之前的JavaScript中:
var obj = {};
src.forEach(function(p) {
return p.split('/').reduce(function(o,name) {
return o[name] = o[name] || {};
}, obj);
});
function convert(obj) {
return Object.keys(obj).map(function(key) {
return Object.keys(obj[key]).length?
{ label: key, children: convert(obj[key])} : { label: key };
});
}
var arr = convert(obj);
我敢说,首先生成自然树,然后转换为数组,这比直接处理数组的任何算法都具有更好的伸缩性,因为查找速度更快,而且对象和文件树之间的自然阻抗匹配更好
JSFiddles:(例如Firefox),.“无法让它工作”不是一个充分的解释。这听起来像是你应该在服务器端做的事情,而不是在角度上。@DavidGrinberg:同样的问题也适用于服务器端。让我们想象一下node.js应用程序。游戏开始:)@戴:我不想用我糟糕的方法影响人们。而且它不起作用。如果没有解决方案弹出,我将在未来几天发布我的无效解决方案…@arcol立即发布。解决方案几乎肯定需要递归。我需要向这个Treeview小部件提供输出:所以我非常坚持上述格式。不,worries,即使进行了转换,我仍然声称这是最有效的解决方案。对象属性是散列查找。您不想对数组进行太多的随机插入操作。谢谢,它正在工作。我更正了jshint错误(将函数移到return上方),否则就是即插即用:)