javascript将嵌套字典转换为树状数组结构

时间:2018-04-16 08:43:14

标签: javascript arrays dictionary tree transformation

我有一个以“a.b.c”,“a.d.e”等形式输入的字符串示例。

我想转换用“。”分隔的字符串部分。以树结构表示。

所以,我编写了下面的函数来从这样一个输入数组创建一个嵌套的字典对象 -

function items_to_tree(items) {
    var arr = {};
    items.forEach(function(item){
        var parts = item.split(".");
        var last = parts.pop();
        var cursor = arr;
        parts.forEach(function(part){
            if(!cursor[part]) cursor[part] = {};
            cursor = cursor[part];
        });
        cursor[last] = {};
    });
    return arr;
}

因此,例如,如果我将以下示例输入提供给此函数 -

var items = ["a.b", "a.c", "b.c", "a.c", "a.c.d", "a.b.d"]

我按预期得到{"a":{"b":{"d":{}},"c":{"d":{}}},"b":{"c":{}}}

但是,我希望输出的格式与此类似 -

[{name: "a", children: [{name: "b", children: [{name: "d", children: []}]}]}, {name: "c", children: [{name: "d", children: []}]}, {name: "b", children: [{name: "c", children: []}]}]

是否有任何方法可以修改items_to_tree函数以返回此类输出,或者 可以从items_to_tree中间输出 [嵌套字典]可以像javascript对象数组一样转换为这个树。

2 个答案:

答案 0 :(得分:1)

您可以在嵌套数组中查找给定名称并使用该对象或创建新对象。

var items = ["a.b", "a.c", "b.c", "a.c", "a.c.d", "a.b.d"],
    result = [];

items.forEach(function (path) {
    path.split('.').reduce(function (level, key) {
        var temp = level.find(({ name }) => key === name);
        if (!temp) {
            temp = { name: key, children: [] };
            level.push(temp);
        }
        return temp.children;
    }, result);
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

我会为最终数据转换编写第二个函数。您的items_to_tree非常通用且可重复使用。将此树转换为所需的格式可以在几行中完成:

function tree_to_format(tree) {
  return Object
    .keys(tree)
    .map(k => ({ name: k, children: tree_to_format(tree[k]) }))
};

现在,您可以通过将items_to_tree的结果汇总到tree_to_format撰写所需的功能:



function items_to_tree(items) {
    var arr = {};
    items.forEach(function(item){
        var parts = item.split(".");
        var last = parts.pop();
        var cursor = arr;
        parts.forEach(function(part){
            if(!cursor[part]) cursor[part] = {};
            cursor = cursor[part];
        });
        cursor[last] = {};
    });
    return arr;
}

function tree_to_format(tree) {
  return Object
    .keys(tree)
    .map(k => ({ name: k, children: tree_to_format(tree[k]) }))
};

console.log(
  tree_to_format(
    items_to_tree(["a.b", "a.c", "b.c", "a.c", "a.c.d", "a.b.d"])
  )
);

// or even:
const compose = (f, g) => x => f(g(x));
const items_to_format = compose(tree_to_format, items_to_tree);