How to convert an array of paths into JSON structu

2019-01-25 21:38发布

I found the question How to convert a file path into treeview?, but I'm not sure how to get the desired result in JavaScript:

I'm trying to turn an array of paths into a JSON tree:

https://jsfiddle.net/tfkdagzv/16/

But my path is being overwritten.

I'm trying to take something like this:

[
    '/org/openbmc/path1', 
    '/org/openbmc/path2', 
    ...
]

... and turn it into...

output = {
   org: {
     openbmc: {
       path1: {},
       path2: {}
     }
   }
}

I'm sure this is pretty easy, but I'm missing something.

3条回答
小情绪 Triste *
2楼-- · 2019-01-25 21:52

Here is a solution I wrote:

var data = [
 "/org/openbmc/examples/path0/PythonObj",
 "/org/openbmc/UserManager/Group",
 "/org/openbmc/HostIpmi/1",
 "/org/openbmc/HostServices",
 "/org/openbmc/UserManager/Users",
 "/org/openbmc/records/events",
 "/org/openbmc/examples/path1/SDBusObj",
 "/org/openbmc/UserManager/User",
 "/org/openbmc/examples/path0/SDBusObj",
 "/org/openbmc/examples/path1/PythonObj",
 "/org/openbmc/UserManager/Groups",
 "/org/openbmc/NetworkManager/Interface"
];

var output = {};
var current;

for(var a=0; a<data.length; a++) {
  var s = data[a].split('/');
  current = output;
  for(var i=0; i<s.length; i++) {
    if(s[i] != '') {
      if(current[s[i]] == null) current[s[i]] = {};
      current = current[s[i]];
    }
  }
}

console.log(output);

It will do everything you need it to, and is compact. But, for the problem in your solution, it has to do with how you are managing current. Specifically, you had this:

current = output[path[0]];

instead of this:

current = output;

which meant that the code to initialize output, would run every time, because path[0] is, in your data, always going to be '', and output[''] doesn't yet exist, so output would always be reset/overwritten.

查看更多
We Are One
3楼-- · 2019-01-25 22:10

This function should do :

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

Demo

var paths = [
    "/org/openbmc/UserManager/Group",
    "/org/stackExchange/StackOverflow",
    "/org/stackExchange/StackOverflow/Meta",
    "/org/stackExchange/Programmers",
    "/org/stackExchange/Philosophy",
    "/org/stackExchange/Religion/Christianity",
    "/org/openbmc/records/events",
    "/org/stackExchange/Religion/Hinduism",
    "/org/openbmc/HostServices",
    "/org/openbmc/UserManager/Users",
    "/org/openbmc/records/transactions",
    "/org/stackExchange/Religion/Islam",
    "/org/openbmc/UserManager/Groups",
    "/org/openbmc/NetworkManager/Interface"
];

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

document.body.innerHTML = '<pre>' +
                          JSON.stringify(parsePathArray(), null, '\t')
                          '</pre>';

(see also this Fiddle)

查看更多
Juvenile、少年°
4楼-- · 2019-01-25 22:13

NB: The resulting arrays need to be merged

This method works for both files & directories, and by using only arrays as the data format.

The structure is based upon arrays being folders, the first element being the folder name and the second - the contents array.

Files are just regular strings inside the array (but could easily be objects containing properties)

Converts =>

[
  '/home/',
  '/home/user/.bashrc',
  '/var/',
  '/var/test.conf',
  '/var/www/',
  '/var/www/index.html',
  '/var/www/index2.html'
]

To =>

[
  ['home', [
    ['user', [
      '.bashrc'
    ]]
  ]],
  ['var', [
    'test.conf',
    ['www', [
      'index.html',
      'index2.html'
    ]]
  ]]
]

 

Script:

var paths = [
  '/var/',
  '/var/test.conf',
  '/var/www/',
  '/var/www/index.html',
  '/var/www/index2.html'
]

var parsed = []

for (let path of paths) {
  let tree = path.split('/')
  let previous = parsed

  console.groupCollapsed(path)
  for (let item in tree) {
    const name = tree[item]
    const last = item == tree.length - 1

    if (name) {
      if (last) {
        console.log('File:', name)
        previous.push(name) - 1
      } else {
        console.log('Folder:', name)
        let i = previous.push([name, []]) - 1
        previous = previous[i][1]
      }  
    }
  }
  console.groupEnd(path)
}

console.warn(JSON.stringify(parsed))
查看更多
登录 后发表回答