Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将路径数组转换为数据结构_Javascript_Arrays_Algorithm - Fatal编程技术网

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;
}