【问题标题】:String path to JsonJson 的字符串路径
【发布时间】:2019-01-08 11:24:20
【问题描述】:

我有如下路径列表。

var paths = [
    "ubx/ubx-producao/Editora Abril/Exame 1106/FINANCAS_INOCAVAO_STARTUP_BANCOES.mp3",
    "ubx/ubx-producao/Editora Alto Astral/Previsoes signos Fevereiro 2016/aquario-fevereiro.mp3",
    "ubx/ubx-producao/Editora Alto Astral/Previsoes signos Fevereiro 2016/aries-fevereiro.mp3"];

我使用下面的代码解析为 JSON。

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

我得到了如下所示的结果:

我最大的困难是让输出如下所示

{
    "text": "ubx",
    "children" : [{
        "text": "ubx-producao",
        "children": [{
            "text": "Editora Abril",
            "children": [{
                "text": "Exame 1106",
                "children": [
                    "BRASIL ECONOMIA DUPLA EXPLOSIVAE.mp3","BRASIL ECONOMIA PRONTOS PARA O JANTAR.mp3"]
                ]
            }]
        },
        {
            "text": "Editora Alto Astral",
            "children": [{
                "text": "Previsoes signos Fevereiro 2016",
                "children": ["aquario-fevereiro.mp3", "aquario-fevereiro.mp3.sfk"]
            }]
        }]
    }]
}

【问题讨论】:

    标签: javascript jquery json parsing


    【解决方案1】:

    我希望编写紧凑的代码。首先,像你所拥有的那样构造一棵树,然后遍历树来格式化节点

    const paths = [
      "ubx/ubx-producao/Editora Abril/Exame 1106/FINANCAS_INOCAVAO_STARTUP_BANCOES.mp3",
      "ubx/ubx-producao/Editora Alto Astral/Previsoes signos Fevereiro 2016/aquario-fevereiro.mp3",
      "ubx/ubx-producao/Editora Alto Astral/Previsoes signos Fevereiro 2016/aries-fevereiro.mp3"
    ];
    
    // first construct a tree like what you have
    const tree = paths.reduce((res, cur) => {
      const arr = cur.split("/");
      const strParent = arr.shift();
      res[strParent] = res[strParent] || {}; 
      let parent = res[strParent];
    
      arr.forEach(item => {
        parent[item] = parent[item] || {};
        parent = parent[item];
      });
      return res;
    }, {});
    
    // traverse the tree to format the results
    const wrap = (parent) => {
      return Object.getOwnPropertyNames(parent).map(name => {
        const node = {
          text: name,
          children: wrap(parent[name])
        };
    
        node.children = node.children.map(c => {
          return c.children.length === 0 ? c.text : c;
        });
    
        return node;
      }); 
    }
    
    console.log(JSON.stringify(wrap(tree), null, 2));
    

    【讨论】:

    • 不错的代码。如此紧凑,像魅力一样工作。非常感谢你!
    【解决方案2】:

    所以我想我得到了你想要的东西

    首先;线程中的输入与预期的输出不匹配。

    例如。 aquario-fevereiro.mp3.sfk 不存在于输入中。

    -- 另外输出格式不正确,所以我做了一些调整。

    这是我假设的预期输出

                let expectedOutput = [{
                "text": "ubx",
                "children" : [
                    {
                        "text": "ubx-producao",
                        "children": [
                            {
                                "text": "Editora Abril",
                                "children": [
                                    {
                                        "text": "Exame 1106",
                                        "children": ["FINANCAS_INOCAVAO_STARTUP_BANCOES.mp3"]
                                    }
                                ]
                            },
                            {
                                "text": "Editora Alto Astral",
                                "children": [
                                    {
                                        "text": "Previsoes signos Fevereiro 2016",
                                        "children": ["aquario-fevereiro.mp3", "aries-fevereiro.mp3"]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }];
    

    代码如下:

    let paths = [
    	"ubx/ubx-producao/Editora Abril/Exame 1106/FINANCAS_INOCAVAO_STARTUP_BANCOES.mp3",
    	"ubx/ubx-producao/Editora Alto Astral/Previsoes signos Fevereiro 2016/aquario-fevereiro.mp3",
    	"ubx/ubx-producao/Editora Alto Astral/Previsoes signos Fevereiro 2016/aries-fevereiro.mp3"
    ];
    let output = convertPathsToStructure(paths);
    console.log(output);
    
    function convertPathToStructure(path) {
        let index = path.indexOf('/');
        return (index > -1) ? {
            text : path.substr(0, index),
            children: convertPathToStructure(path.substr(index + 1)),
        } : path;
    }
    function convertPathsToStructure(paths) {
        return convertTreeStructuresToStructure(paths.map(convertPathToStructure));
    }
    function convertTreeStructuresToStructure(treeStructures) {
        let isObjects = treeStructures.filter(result => result.hasOwnProperty('text')).length > 0;
        if (!isObjects) return treeStructures;
    
        let allObjs = {};
        treeStructures.forEach(({text = '', children = []}) => {
            let obj = allObjs[text] || {text: '', children: []};
            obj.text = text;
            obj.children.push(children);
            allObjs[text] = obj;
        });
    
        return Object.keys(allObjs).map(text => {
            return {
                text: text,
                children: convertTreeStructuresToStructure(allObjs[text].children)
            }
        });
    }

    【讨论】:

    • 感谢您的注释和帮助。你的代码工作就像一个魅力。但是@D.Seah 的代码更紧凑。
    • 是的,我只是认为测试单个组件会更好。
    • 而且你应该考虑给我的帖子至少投一个赞成票,因为我是第一个回答正确答案的人。
    • 29 行与 28 行。
    • 我投了赞成票,但我的声誉不到 15 岁。所以它没有向公众展示
    猜你喜欢
    • 2019-03-30
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多