【问题标题】:Recursive function to build breadcrumbs from json menu object从 json 菜单对象构建面包屑的递归函数
【发布时间】:2018-02-28 12:38:57
【问题描述】:

所以我一直在努力解决这个递归函数并获得正确的结果。

const _ = require('lodash');

let config = {
    "Main": {
        children: {
            "Dashboard": "main.dashboard",
            "Account": {
                children: {
                    "Settings": "main.account.settings"
                }
            }
        }
    },
    "Statistics": {
        children: {
            "Test One": "main.statistics.test.one",
            "Test Two": "main.statistics.test.two"
        }
    }
}

let processNav = (config, parent) => {
    let children;
    let results = {};

    _.forOwn(config, (value, title) => {
        var breadcrumb = parent || title;

        if (value.children) {
            children = processNav(value.children, breadcrumb);
            _.assign(results, children);
        } else {
            results[value] = [breadcrumb, title];
        }
    });

    return results;
};

let breadcrumbs = processNav(config);

console.log(breadcrumbs);

// output
{ 'main.dashboard': [ 'Main', 'Dashboard' ],
  'main.account.settings': [ 'Main', 'Settings' ],
  'main.statistics.test.two': [ 'Statistics', 'Test Two' ] }

我正在寻找的输出更像是这样的......

// expected output
{ 'main.dashboard': [ 'Main', 'Dashboard' ],
  'main.account.settings': [ 'Main', 'Account', 'Settings' ],
  'main.statistics.test.one': [ 'Statistics', 'Test One' ],
  'main.statistics.test.two': [ 'Statistics', 'Test Two' ] }

在我发疯之前谁能帮我解决这个问题?

【问题讨论】:

  • main.statistics.test.one在哪里?
  • 感谢您的关注,我已经更新了 q

标签: javascript recursion lodash


【解决方案1】:

这种方法不使用.lodash,只使用普通的JS。

let config = {    "Main": {        children: {            "Dashboard": "main.dashboard",            "Account": {                children: {                    "Settings": "main.account.settings"                }            }        }    },    "Statistics": {        children: {            "Test One": "main.statistics.test.one",            "Test Two": "main.statistics.test.two"        }    }};

function loop(obj, path, breadcrumbs) {
  Object.keys(obj).forEach(k => {        
    if (obj[k].children) loop(obj[k].children, [...path, k], breadcrumbs);
    else breadcrumbs[obj[k]] = [...path, k];    
  });
}

let breadcrumbs  = {};
loop(config, [], breadcrumbs);

console.log(JSON.stringify(breadcrumbs, null, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    主要的困难是跳过children 对象。因此,我在递归模式中加入了一个额外的案例。

    如果当前“节点”具有children 属性,它会通过立即调用下一个递归来“跳过”它:

    isParent(obj) ? getPaths(obj.children, path, result) : /* ... * /
    

    在行动:

    const config={Main:{children:{Dashboard:"main.dashboard",Account:{children:{Settings:"main.account.settings"}}}},Statistics:{children:{"Test One":"main.statistics.test.one","Test Two":"main.statistics.test.two"}}};
    
    const isParent = x => x.children;
    const isLeaf = x => typeof x === "string";
    
    const getPaths = (obj, path = [], result = {}) => 
      isParent(obj)
        // The "Skip" case:
        ? getPaths(obj.children, path, result)
        : isLeaf(obj)
          // The *final* case:
          ? Object.assign(result, { [obj]: path })
          // The *recurse* case:
          : Object.keys(obj).reduce(
          	(r, k) => getPaths(obj[k], path.concat(k), r),
            result);
            
    console.log(getPaths(config));

    【讨论】:

      猜你喜欢
      • 2011-05-02
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 2014-07-17
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多