将对象数组(使用字符串数组元素)转换为嵌套树

时间:2018-01-02 07:36:11

标签: javascript arrays

我一直试图解决数组和对象的问题已经有一段时间了 - 但我仍然无法找到正确的解决方案。

这是我的首发位置:

list = [
{
    lastItemData: {data:"root"},
    path: ["Root"]
},
{
    lastItemData: {data:"level2_Summer"},
    path: ["Root", "Level2_Summer"]
},
{
    lastItemData: {data:"Level3_Monday"},
    path: ["Root", "Level2_Winter", "Level3_Monday"]
},
{
    lastItemData: {data:"Level4_Morning"},
    path: ["Root", "Level2_Spring", "Level3_Tuesday", "Level4_Morning"]
},
{
    lastItemData: {data:"Level3_Sunday"},
    path: ["Root", "Level2_Autumn", "Level3_Sunday"]
}]

这就是我需要的:

result = [
{
    text: "Root",
    lastItemData: {data:"root"},
    Items:[
        {
            text:"Level2_Summer",
            lastItemData: {data:"level2_Summer"},
            Items: []
        },
        {
            text:"Level2_Winter",
            Items:[
                {
                    text: "Level3_Monday",
                    lastItemData: {data:"Level3_Monday"},
                    Items: []
                }
            ]
        },
        {
            text:"Level2_Spring",
            Items:[
                {
                    text: "Level3_Tuesday"
                    Items: [
                        {
                            text:"Level4_Morning"
                            Items:[],
                            lastItemData: {data:"Level4_Morning"},
                        }
                    ]
                }
            ]
        },
        {
            text:"Level2_Autumn",
            Items:[
                {
                    text: "Level3_Sunday"
                }
            ]
        },
    ]
}]

我尝试这样的事情(代码基于用户jonas从我删除的帖子回答)

const property = list.reduce((previous, current, index) => {


            let acc = {}; //the accumulator that will go deep into the object
            const result = acc; //our result will be the top level object

            debugger;

            //Now we iterate over our array
            for (var i = 0; i < current.stringPath.length; i++) {
                debugger;
                //add the string part
                acc["level" + (i + 1)] = current.stringPath[i];
                //Add the children array
                acc["Items"] = [{}];
                //And go into the object
                acc = acc["Items"][0];
            }

            console.log(result)

            previous.push(result);

            return previous;

        }, []);

        console.log("property", property);

但不幸的是,结果并不符合所需的结构。任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

这是一个复杂得多的问题,因为你必须构建一个具有给定名称(text属性)的嵌套结构,并且需要检查该名称是否存在。如果没有创建新对象并将其推送到父数组。

此解决方案具有哈希表,其中收集和维护每个级别的所有嵌套哈希。结果是一个包含所需树的数组。

它的工作原理如下:

首先查看哈希表的根,并检查路径值是否存在。如果没有,请使用该信息创建一个新节点,并将其推送到哈希收集器,用_表示。然后返回该节点并继续迭代给定路径。

在路径和路径上使用lastItemData作为所需对象。

var list = [{ lastItemData: { data: "root" }, path: ["Root"] }, { lastItemData: { data: "level2_Summer" }, path: ["Root", "Level2_Summer"] }, { lastItemData: { data: "Level3_Monday" }, path: ["Root", "Level2_Winter", "Level3_Monday"] }, { lastItemData: { data: "Level4_Morning" }, path: ["Root", "Level2_Spring", "Level3_Tuesday", "Level4_Morning"] }, { lastItemData: { data: "Level3_Sunday" }, path: ["Root", "Level2_Autumn", "Level3_Sunday"] }],
    tree = function (array) {
        var result = [],
            hash = { _: { Items: result } };

        array.forEach(function (object) {
            object.path.reduce(function (o, p) {
                if (!o[p]) {
                    o[p] = { _: { text: p, Items: [] } };
                    o._.Items.push(o[p]._);
                }
                return o[p];
            }, hash)._.lastItemData = object.lastItemData;
        });
        return result;
    }(list);

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