Javascript 将路径数组转换为数据结构
我有一组路径,如下所示:Javascript 将路径数组转换为数据结构,javascript,arrays,algorithm,Javascript,Arrays,Algorithm,我有一组路径,如下所示: /doc/data/main.js /doc/data/xl.js /doc/data/dandu/sdasa.js /mnt/data/la.js 我正在尝试构建以下结构: { "directories": { "/doc/data": { "directories": { "dandu": { "files"
/doc/data/main.js
/doc/data/xl.js
/doc/data/dandu/sdasa.js
/mnt/data/la.js
我正在尝试构建以下结构:
{
"directories": {
"/doc/data": {
"directories": {
"dandu": {
"files": {
"sdasa.js": 1
}
}
},
"files": {
"main.js": 1,
"xl.js": 1
}
},
"/mnt/data": {
"directories": {},
"files": {
"la.js": 1
}
}
},
"files": {}
}
请忽略该示例中文件的值。我将在将来为此分配更复杂的数据。当前值为1
从上一篇文章中,我发现我可以使用以下函数来获得类似的结果:
var parsePathArray = function() {
var parsed = {};
for(var i = 0; i < paths.length; i++) {
var position = parsed;
var split = paths[i].split('/');
for(var j = 0; j < split.length; j++) {
if(split[j] !== "") {
if(typeof position[split[j]] === 'undefined')
position[split[j]] = {};
position = position[split[j]];
}
}
}
return parsed;
}
将这些字符串转换为该数据结构的最佳方法是什么?您可以使用某种递归函数来完成。请记住,这只是一个可能的解决方案,可能不是最好的
const workPath = (path, structure) => {
if(!structure) structure = {};
const folders = path.split("/");
const file = folders.pop();
// Check weather any of the possible paths are available
let breakPoint = null;
let tempPath;
for(let i = 0; i< folders.length; i++){
const copy = [... folders];
tempPath = copy.splice(0, i+1).join("/");
if(structure[tempPath]){
breakPoint = i;
break;
}
}
// If there was no path available, we create it in the structure
if(breakPoint == null){
const foldersPath = folders.join("/");
structure[foldersPath]= {};
structure[foldersPath]["files"] = {};
structure[foldersPath]["files"][file] = 1;
}
// If there is a path inside of the structure, that also is the entire path we are working with,
// We just add the file to the path
else if(breakPoint && breakPoint == folders.length - 1){
structure[folders.join("/")]["files"][file] = 1;
}
// If we get here, it means that some part of the path is available but not the entire path
// So, we just call the workPath function recursively with only one portion of the path
else{
const subPath = folders.splice(breakPoint + 1).join("/") + "/" + file;
structure[tempPath]["directories"] = workPath(subPath, structure[tempPath]["directories"]);
}
return structure;
}
const convert = array => {
let structure = {};
for(let path of array){
structure = workPath(path, structure);
}
return structure;
}
const workPath=(路径、结构)=>{
如果(!structure)structure={};
const folders=path.split(“/”);
const file=folders.pop();
//检查是否有任何可能的路径可用
设断点=null;
让我们走这条路;
for(设i=0;i{
let结构={};
for(数组的let路径){
结构=工作路径(路径、结构);
}
回报结构;
}
“convert”函数需要一个包含所有路径的数组
记住,这个解决方案不考虑没有文件的条目。
< P>这是我提出的解决方案。它的工作原理是一次构建一条路径,并将其与现有数据结构进行比较。它还应该自己处理文件,因为你原来的帖子似乎暗示这是必要的。最后我决定把它分成两个函数,因为这样可能会更容易解释 代码:const路径=[
“/doc/data/main.js”,
“doc/data/xl.js”,
“/etc/further/owy.js”,
“/etc/further/abc.js”,
“etc/mma.js”,
“/mnt/data/it.js”,
“/mnt/data/path/is/long/la.js”,
'mnt/data/path/is/la.js',
“/doc/data/dandu/sdasa.js”,
“/etc/i/j/k/l/thing.js”,
“/etc/i/j/areallylongname.js”,
'thing.js'
];
函数构建结构(路径){
let结构={
目录:{},
文件:{}
};
常量比较=(a,b)=>{
返回a.split('/').length-b.split('/').length;
};
[…路径]
.map(path=>path=path.charAt(0)='/'?路径:`/${path}`)
.sort((a,b)=>比较(a,b)).forEach(路径=>{
const nodes=path.split('/').slice(1);
const file=nodes.pop();
让指针=findDirectory(节点[0]?结构。目录:结构,,[…节点]);
pointer.files=pointer.files | |{};
指针文件={
…指针文件,
[档案]:1
};
});
回报结构;
};
函数findDirectory(指针、子路径、节点){
如果(nodes.length==0){
如果(子路径){
指针[子路径]={};
指针=指针[子路径];
};
返回指针;
};
设newPath=`${subPath}/${nodes[0]}`;
nodes.shift();
if(指针[新路径]){
指针=指针[newPath];
如果(nodes.length>=1){
pointer.directories=pointer.directories | |{};
指针=指针.目录;
};
新路径=“”;
};
返回findDirectory(指针、新路径、节点);
};
const structure=buildStructure(路径);
控制台日志(结构)代码>
。作为控制台包装{min height:100%!important;top:0;}
这个挑战其实并不是那么简单。尽管如此,该方法仍然适用于,人们可以考虑,易于阅读和理解,从而维护可执行的子任务,以达到OP的目标…
const路径列表=[
“/doc/data/main.js”,
“/doc/data/fame.js”,
“/doc/data/fame.es”,
“/doc/data/xl.js”,
“/doc/data/dandu/sdasa.js”,
“/mnt/data/la.js”,
“/mnt/la.es”,
'foo/bar/baz/biz/foo.js',
'foo/bar/baz/biz/bar.js',
“/foo/bar.js”,
“/foo/bar/baz/foo.js”,
'foo/bar/baz/bar.js',
'foo/bar/baz/biz.js',
“/foobar.js”,
“bazbiz.js”,
“/etc/further/owy.js”,
“/etc/further/abc.js”,
“etc/mma.js”,
“/etc/i/j/k/l/thing.js”,
“/etc/i/j/areallylongname.js”
];
函数createSeparatedPathAndFileData(路径){
const regXReplace=(/^\/+/);//用于替换“path”中的前导斜杠序列。
const regXSplit=(//\/([^/]*)$/);//用于检索分离的路径和文件名数据。
const filePartials=path.replace(regXReplace.).split(regXSplit);
if(filePartials.length==1){
//确保至少有一个空的“路径名”。
filePartials.unshift(“”);
}
const[pathName,fileName]=filePartials;
返回{
路径名,
文件名
};
}
函数compareByPathAndFileNameAndExtension(a,b){
const regXSplit=(/\。([^.]*)$/);//拆分文件名和捕获的文件扩展名。
const[aName,aExtension]=a.fileName.split(regXSplit);
const[bName,bExtension]=b.fileName.split(regXSplit);
重新
const workPath = (path, structure) => {
if(!structure) structure = {};
const folders = path.split("/");
const file = folders.pop();
// Check weather any of the possible paths are available
let breakPoint = null;
let tempPath;
for(let i = 0; i< folders.length; i++){
const copy = [... folders];
tempPath = copy.splice(0, i+1).join("/");
if(structure[tempPath]){
breakPoint = i;
break;
}
}
// If there was no path available, we create it in the structure
if(breakPoint == null){
const foldersPath = folders.join("/");
structure[foldersPath]= {};
structure[foldersPath]["files"] = {};
structure[foldersPath]["files"][file] = 1;
}
// If there is a path inside of the structure, that also is the entire path we are working with,
// We just add the file to the path
else if(breakPoint && breakPoint == folders.length - 1){
structure[folders.join("/")]["files"][file] = 1;
}
// If we get here, it means that some part of the path is available but not the entire path
// So, we just call the workPath function recursively with only one portion of the path
else{
const subPath = folders.splice(breakPoint + 1).join("/") + "/" + file;
structure[tempPath]["directories"] = workPath(subPath, structure[tempPath]["directories"]);
}
return structure;
}
const convert = array => {
let structure = {};
for(let path of array){
structure = workPath(path, structure);
}
return structure;
}