如何从点符号字符串动态创建多级对象

How to dynamically create a multilevel object from a dot notation string

我有一些数据需要格式化。输入类似于

const data = [
            ['0','some name','ok'],
            ['0.1','some name','ok'],
            ['0.1.01','some name', 'ok'],
            ['0.1.01.01','some name','ok'],
            ['0.1.01.02','some name','ok'],
            ['1','some name','ok'],

        ]

我需要它像:

const data = [{
    code: "0"
    name: "some name"
    status: "ok"
    data:[{
        code: "0.1"
        name: "some name"
        status: "ok"
        data:[
        {
            code: "0.1.01"
            name: "some name"
            status: "ok"
            data: []
        },
        {
            code: "0.1.02"
            name: "some name"
            status: "ok"
            data:[]
        }
        ]
    },
    {
    code: "1"
    name: "some name"
    status: "ok"
    data[]
    }
    
    ]
}]

我将使用此数据来填充可扩展的反应 table,我需要那种结构,因此 useExpanded 可以像这样处理可扩展的行

  code       | decription  | status
__________________________________
- 0          |  some text  | ok
  - 0.1      |  some text  | ok
    + 0.1.01 |  some text  | ok
    + 0.1.02 |  some text  | ok
+ 1          |  some text  | ok

所以'code'代表关卡,每个关卡都是一个对象数组

这是我到目前为止尝试过的方法。

const formatData = () => {
        const data = [
            ['0','some name','ok'],
            ['0.1','some name','ok'],
            ['0.1.01','some name', 'ok'],
            ['0.1.01.01','some name','ok'],
            ['0.1.01.02','some name','ok'],
        ]
        const columnName = ['code','name','status']

        const result = []; 
        data.forEach((item) => {
        
            let rowInfo = {}; 
            item.forEach((item, index) => {
                rowInfo = { ...rowInfo, [columnName[index]]: item };
            });
            if (item[0].split(".").length === 1) { // If is the first level
                result.push({ ...rowInfo, subRows: [] });
            } else {
                let aux = item[0].split(".");
                aux.slice(0, -1).reduce((r, e) => { // find parent and push object to array
                    r[e].subRows.push({ ...rowInfo, subRows: [] });
                }, result);
            }
        });
        return result;
    }
    

我可以得到前 3 行,但程序在尝试查找子级数组时中断

首先:运行 您在调试器中的代码,看看它在做什么。不是你想的那样。

也许阅读 reduce() 的作用。

其次,重写它,这样您就不会在树中搜索插入行的位置。树的所有节点都有 ID,因此只需制作从这些 ID 到节点的映射。当你想找到一个节点时,只需在地图中查找它即可。

终于解决了

这是解决方案:

var array = ["1","1.1","1.1.01","1.1.02.1",'1.2.01' ];

    result = array.reduce((r, s,rowNum) => {
        const size = s.split(".").length-1
        s.split('.').reduce((a, path,index) => 
            let object = a.find(o => o.path === path);
            if (!object && index===size) { // If object is not created and is the last child
                //create object
                a.push(object = { path, populate: [] });
            } else {
                 // If object is not created but isn't the last
                if(!object) throw `Error: ${rowNum}`; // parent object has not been created, notify user
            }
            return object.populate; // If there is an object and is not the last child, return it's own array of objects (child list)
        }, r);
        return r;
    }, []);
    
console.log(result);


我使用第一个 reduce 从数组中获取每个项目并将其累积到一个数组中,然后我得到字符串将生成的“级别”数。

第二个 reduce 函数迭代将要创建的关卡。

如果是最后一级(或者如果它只有一级),那么我创建对象和 return 将包含子级对象的子数组,因此下一次迭代中的累加器是现在是子级别数组的引用。然后我检查是否是最后一级,如果不是,则 return 子级数组,如果对象不存在,则错误