最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Parse string of file path to json object - Stack Overflow

programmeradmin2浏览0评论

I have the list of URL like below. How to convert it into plete json object?

My array of URLs.

[
"path1/subpath1/file1.doc","path1/subpath1/file2.doc","path1/subpath2/file1.doc","path1/subpath2/file2.doc","path2/subpath1/file1.doc","path2/subpath1/file2.doc","path2/subpath2/file1.doc","path2/subpath2/file2.doc","path2/subpath2/additionalpath1/file1.doc"
]

I want this as json object like:

{
   "path1":{
      "subpath1":["file1.doc","file2.doc"],
      "subpath2":["file1.doc","file2.doc"]
   },
   "path2":{
      "subpath1":["file1.doc","file2.doc"],
      "subpath2":["file1.doc","file2.doc"],
      "additionalpath1":{
          "additionalpath1":["file1.doc"]
      }
   }
}

How to do this?

I tried it with the below code snippets. But there are few folder objects are missing.

If you try this code you will find that test1 and additional objects are missing:

<html>
  <script src=".10.2.js"></script>
<body>


<p id="demo"></p>

<script>
let paths = [ "admin/640954.jpg", "admin/test1/3m-nd.jpg", 
"admin/test1/Acct.png", "admin/test1/additional/111.gif", "admin/test1/additional/Aard.jpg", 
"dp/151292.jpg", "dp/151269.jpg", "dp/1515991.jpg" ];


function getMap(urls){
    var map = {};
    urls.forEach(function(url){
        var parts = url.split("/");
        makePath(map, parts);
    })
    return map;
}

function makePath(map,parts){
    var currentPath = map;
    for(var i = 0 ; i < parts.length - 1 ; i++ ){
            if(i == parts.length -2 ){
                currentPath[parts[i]]  = currentPath[parts[i]] || [];
                currentPath[parts[i]].push(parts[++i]);
            }else{
                currentPath[parts[i]] =  currentPath[parts[i]] || {};
                currentPath = currentPath[parts[i]];
            }
    }

}

document.getElementById("demo").innerHTML=JSON.stringify(getMap(paths));
</script>

</body>
</html>

I have the list of URL like below. How to convert it into plete json object?

My array of URLs.

[
"path1/subpath1/file1.doc","path1/subpath1/file2.doc","path1/subpath2/file1.doc","path1/subpath2/file2.doc","path2/subpath1/file1.doc","path2/subpath1/file2.doc","path2/subpath2/file1.doc","path2/subpath2/file2.doc","path2/subpath2/additionalpath1/file1.doc"
]

I want this as json object like:

{
   "path1":{
      "subpath1":["file1.doc","file2.doc"],
      "subpath2":["file1.doc","file2.doc"]
   },
   "path2":{
      "subpath1":["file1.doc","file2.doc"],
      "subpath2":["file1.doc","file2.doc"],
      "additionalpath1":{
          "additionalpath1":["file1.doc"]
      }
   }
}

How to do this?

I tried it with the below code snippets. But there are few folder objects are missing.

If you try this code you will find that test1 and additional objects are missing:

<html>
  <script src="https://code.jquery./jquery-1.10.2.js"></script>
<body>


<p id="demo"></p>

<script>
let paths = [ "admin/640954.jpg", "admin/test1/3m-nd.jpg", 
"admin/test1/Acct.png", "admin/test1/additional/111.gif", "admin/test1/additional/Aard.jpg", 
"dp/151292.jpg", "dp/151269.jpg", "dp/1515991.jpg" ];


function getMap(urls){
    var map = {};
    urls.forEach(function(url){
        var parts = url.split("/");
        makePath(map, parts);
    })
    return map;
}

function makePath(map,parts){
    var currentPath = map;
    for(var i = 0 ; i < parts.length - 1 ; i++ ){
            if(i == parts.length -2 ){
                currentPath[parts[i]]  = currentPath[parts[i]] || [];
                currentPath[parts[i]].push(parts[++i]);
            }else{
                currentPath[parts[i]] =  currentPath[parts[i]] || {};
                currentPath = currentPath[parts[i]];
            }
    }

}

document.getElementById("demo").innerHTML=JSON.stringify(getMap(paths));
</script>

</body>
</html>
Share Improve this question edited Apr 7, 2018 at 16:22 Shajal Ahamed 1412 silver badges16 bronze badges asked Apr 7, 2018 at 5:30 ShakthiShakthi 8644 gold badges15 silver badges41 bronze badges 6
  • You can do this with a recursive mapping algorithm. – Zze Commented Apr 7, 2018 at 5:33
  • In which language are you coding? – Mohit Mutha Commented Apr 7, 2018 at 5:33
  • @MohitMutha Look at the tags. – Zze Commented Apr 7, 2018 at 5:33
  • You could grab everything after the last forward slash. What have you already tried? – Anthony Commented Apr 7, 2018 at 5:34
  • 2 Possible duplicate of How to convert an array of paths into JSON structure? – Anthony Commented Apr 7, 2018 at 5:36
 |  Show 1 more ment

5 Answers 5

Reset to default 1

You could use .split("/") and iterate over the results, creating properties in nested objects:

let paths = [
  "path1/subpath1/file111.doc",
  "path1/subpath1/file112.doc",
  "path1/subpath2/file121.doc",
  "path1/subpath2/file122.doc",
  "path2/subpath1/file211.doc",
  "path2/subpath1/file212.doc",
  "path2/subpath2/file221.doc",
  "path2/subpath2/file222.doc",
  "path2/additionalpath3/additionalpath1/file2311.doc"
];

let treePath = {};
paths.forEach(path => {
  let levels = path.split("/");
  let file = levels.pop();

  let prevLevel = treePath;
  let prevProp = levels.shift();

  levels.forEach(prop => {
    prevLevel[prevProp] = prevLevel[prevProp] || {};
    prevLevel = prevLevel[prevProp];
    prevProp = prop;
  });

  prevLevel[prevProp] = (prevLevel[prevProp] || []).concat([file]);
});

console.log(treePath);

Or:

let paths = [
  "path1/subpath1/file111.doc",
  "path1/subpath1/file112.doc",
  "path1/subpath2/file121.doc",
  "path1/subpath2/file122.doc",
  "path2/subpath1/file211.doc",
  "path2/subpath1/file212.doc",
  "path2/subpath2/file221.doc",
  "path2/subpath2/file222.doc",
  "path2/additionalpath3/additionalpath1/file2311.doc"
];

let treePath = {};
paths.forEach(path => {
  let levels = path.split("/");
  let file = levels.pop();

  levels.reduce((prev, lvl, i) => {
    return prev[lvl] = (levels.length - i - 1) ? prev[lvl] || {} : (prev[lvl] || []).concat([file]);
  }, treePath);
});

console.log(treePath);

I have made Half code for you. check if it is helpful for you.

You can use it and can made some changes to achieve your goal.

<!DOCTYPE html>
<html>
  <script src="https://code.jquery./jquery-1.10.2.js"></script>
<body>

<p>Click the button to display the array values after the split.</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {
    var str = '"path1/subpath1/file1.doc","path1/subpath1/file2.doc","path1/subpath2/file1.doc","path1/subpath2/file2.doc","path2/subpath1/file1.doc","path2/subpath1/file2.doc","path2/subpath2/file1.doc","path2/subpath2/file2.doc","path2/subpath2/additionalpath1/file1.doc"';
    var res = str.split(",");
    document.getElementById("demo").innerHTML = res[0];

    var finalresult = [];
    var innerarray = [];
    var outer = [];
    var outer1 = [];
    var inner =[];
    jQuery.each( res, function( i, val ) {
      res1 = val.split("/");
      jQuery.each( res1, function( i2, val1 ) 
      {
            if(i2 == 0 && !(outer.includes(val1)))
            {
                outer.push(val1);
            }
            else if(i2 == 1 && !(outer1.includes(val1)))
            {
                outer1.push(val1);
            }
            else if(!(inner.includes(val1)))
            {
                inner.push(val1);
            }
        console.log(outer);
      });

    });

}
</script>

</body>
</html>
function filePathOject (arr) {
  const ret = {};
  arr.forEach((path) => {
    const dirs = path.split('/');
    const filename = dirs.pop();

    let dirObject = ret;
    dirs.forEach((dir, i) => {
      if (i === dirs.length - 1) {
        dirObject[dir] = dirObject[dir] || [];
        dirObject[dir].push(filename);
      } else {
        dirObject[dir] = dirObject[dir] || {};
      }
      dirObject = dirObject[dir];
    });
  });

  return ret;
}

You can do something like this.

var urls = [
"path1/subpath1/file1.doc","path1/subpath1/file2.doc","path1/subpath2/file1.doc","path1/subpath2/file2.doc","path2/subpath1/file1.doc","path2/subpath1/file2.doc","path2/subpath2/file1.doc","path2/subpath2/file2.doc","path2/subpath2/additionalpath1/file1.doc"
]

function getMap(urls){
var map = {};

urls.forEach(function(url){
    var parts = url.split("/");
    makePath(map, parts);
})
return map;
}

function makePath(map,parts){
    var currentPath = map;
    for(var i = 0 ; i < parts.length - 1 ; i++ ){
            if(i == parts.length -2 ){
                currentPath[parts[i]]  = currentPath[parts[i]] || [];
                currentPath[parts[i]].push(parts[++i]);
            }else{
                currentPath[parts[i]] =  currentPath[parts[i]] || {};
                currentPath = currentPath[parts[i]];
            }
    }

}
getMap()

Left one part for you :)

Maybe you'd prefer to have subdirs in arrays too


const path = '/home/user/dir/file';
var next;

path.split('/').reverse().forEach(name => {
  if (name === "") return;
  if (typeof(next) === 'undefined') {
    next = [String(name)];
  } else {
    var current = {};
    current[name] = next;
    next = [current];
  }
});
console.log(JSON.stringify(next));
// [{"home":[{"user":[{"dir":["file"]}]}]}]

Then objects can be joined

发布评论

评论列表(0)

  1. 暂无评论