将嵌套对象数组排序为单独的数组数组

Sort array of nested objects into separate array of arrays

我有一个数组:

[ 
  { id: 1, 
    name: "parent1", 
    children: [ 
               { id: 10, 
                 name: "first_child_of_id_1", 
                 children: [ 
                            { id: 100, name: "child_of_id_10", children: []},
                            { id: 141, name: "child_of_id_10", children: []}, 
                            { id: 155, name: "child_of_id_10", children: []}
                           ]
               },
               { id: 42, 
                 name: "second_child_of_id_1", 
                 children: [ 
                            { id: 122, name: "child_of_id_42", children: []},
                            { id: 133, name: "child_of_id_42", children: []}, 
                            { id: 177, name: "child_of_id_42", children: []}
                           ]
               }
             ]
  },
  { id: 7, 
    name: "parent7", 
    children: [ 
               { id: 74, 
                 name: "first_child_of_id_7", 
                 children: [ 
                            { id: 700, name: "child_of_id_74", children: []},
                            { id: 732, name: "child_of_id_74", children: []}, 
                            { id: 755, name: "child_of_id_74", children: []}
                           ]
               },
               { id: 80, 
                 name: "second_child_of_id_7", 
                 children: [ 
                            { id: 22, name: "child_of_id_80", children: []},
                            { id: 33, name: "child_of_id_80", children: []}, 
                            { id: 77, name: "child_of_id_80", children: []}
                           ]
               }
             ]
  }
] 

我需要的是这样的数组:

[
  [ "id", "name", "parent_id", "parent_name" ],
  [  1, "parent1", null, "" ],
  [ 10, "first_child_of_id_1", 1, "parent1"],
  [ 42, "second_child_of_id_1", 1, "parent1"],
  [100, "child_of_id_10", 10, "first_child_of_id_1"]
]

依此类推所有嵌套对象,以便我将它们转换为 CSV 行。我检查了很多答案并在这里发现了类似的问题: 但是它会为许多嵌套对象生成太长的行,而且我对 JavaScript 没有足够的经验来修改 map 函数。

const categories = [ 
                { id: 1, 
                name: "parent1", 
                children: [ 
                            { id: 10, 
                            name: "first_child_of_id_1", 
                            children: [ 
                                        { id: 100, name: "child_of_id_10", children: []},
                                        { id: 141, name: "child_of_id_10", children: []}, 
                                        { id: 155, name: "child_of_id_10", children: []}
                                        ]
                            },
                            { id: 42, 
                            name: "second_child_of_id_1", 
                            children: [ 
                                        { id: 122, name: "child_of_id_42", children: []},
                                        { id: 133, name: "child_of_id_42", children: []}, 
                                        { id: 177, name: "child_of_id_42", children: []}
                                        ]
                            }
                        ]
                },
                { id: 7, 
                name: "parent7", 
                children: [ 
                            { id: 74, 
                            name: "first_child_of_id_7", 
                            children: [ 
                                        { id: 700, name: "child_of_id_74", children: []},
                                        { id: 732, name: "child_of_id_74", children: []}, 
                                        { id: 755, name: "child_of_id_74", children: []}
                                        ]
                            },
                            { id: 80, 
                            name: "second_child_of_id_7", 
                            children: [ 
                                        { id: 22, name: "child_of_id_80", children: []},
                                        { id: 33, name: "child_of_id_80", children: []}, 
                                        { id: 77, name: "child_of_id_80", children: []}
                                        ]
                            }
                        ]
                }
            ] 


    function pivot(arr) {
        var mp = new Map();

        function setValue(a, path, val) {
            if (Object(val) !== val) { // primitive value
                var pathStr = path.join('.');
                var i = (mp.has(pathStr) ? mp : mp.set(pathStr, mp.size)).get(pathStr);
                a[i] = val;
            } else {
                for (var key in val) {
                    setValue(a, key == '0' ? path : path.concat(key), val[key]);
                }
            }
            return a;
        }

        var result = arr.map(obj => setValue([], [], obj));
        return [[...mp.keys()], ...result];
    }


    function toCsv(arr) {
        return arr.map(row =>
            row.map(val => isNaN(val) ? JSON.stringify(val) : +val).join(',')
        ).join('\n');
    }
<button onclick="console.log(toCsv(pivot(categories)))">Output</button>

简单的 DFS 或 BFS 算法应该可以完成这里的工作。 区别在于创建的顺序"rows"。
如果你想让给定节点的所有子节点紧跟在它们的父节点之后,那么你需要使用 BFS。

DFS 和 BFS 示例:

const input = [{
        id: 1,
        name: "parent1",
        children: [{
                id: 10,
                name: "first_child_of_id_1",
                children: [{
                        id: 100,
                        name: "child_of_id_10",
                        children: []
                    },
                    {
                        id: 141,
                        name: "child_of_id_10",
                        children: []
                    },
                    {
                        id: 155,
                        name: "child_of_id_10",
                        children: []
                    }
                ]
            },
            {
                id: 42,
                name: "second_child_of_id_1",
                children: [{
                        id: 122,
                        name: "child_of_id_42",
                        children: []
                    },
                    {
                        id: 133,
                        name: "child_of_id_42",
                        children: []
                    },
                    {
                        id: 177,
                        name: "child_of_id_42",
                        children: []
                    }
                ]
            }
        ]
    },
    {
        id: 7,
        name: "parent7",
        children: [{
                id: 74,
                name: "first_child_of_id_7",
                children: [{
                        id: 700,
                        name: "child_of_id_74",
                        children: []
                    },
                    {
                        id: 732,
                        name: "child_of_id_74",
                        children: []
                    },
                    {
                        id: 755,
                        name: "child_of_id_74",
                        children: []
                    }
                ]
            },
            {
                id: 80,
                name: "second_child_of_id_1",
                children: [{
                        id: 22,
                        name: "child_of_id_80",
                        children: []
                    },
                    {
                        id: 33,
                        name: "child_of_id_80",
                        children: []
                    },
                    {
                        id: 77,
                        name: "child_of_id_80",
                        children: []
                    }
                ]
            }
        ]
    }
]

//DFS
function deepWalk(node, parent, output = []) {
    if (!node || typeof node !== 'object' || !node.id) return;

    output.push([node.id, node.name, parent ? parent.id : null, parent ? parent.name : ""])
    if (node.children) {
        for (const child of node.children) {
            deepWalk(child, node, output);
        }
    }

    return output;
}

//BFS
function broadWalk(root) {
    const output = []
    const queue = [];
    queue.push({
        node: root,
        parent: null
    });
    while (queue.length) {
        const {
            node,
            parent
        } = queue.shift();
        output.push([node.id, node.name, parent ? parent.id : null, parent ? parent.name : ""])
        if (node.children) {
            for (const child of node.children) {
                queue.push({
                    node: child,
                    parent: node
                });
            }
        }
    }
    return output;
}




let rowsDfs = [
    ["id", "name", "parent_id", "parent_name"]
];
let rowsBfs = [
    ["id", "name", "parent_id", "parent_name"]
];
for (const node of input) {
    rowsDfs = [...rowsDfs, ...deepWalk(node)];
    rowsBfs = [...rowsBfs, ...broadWalk(node)];

}

console.log("rows DFS: ", rowsDfs)
console.log("rows BFS: ", rowsBfs)