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

问题描述 投票:0回答:1

我有一个数组:

[ 
  { 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行。我检查了很多答案,并在这里发现了类似的问题:How to convert array of nested objects to CSV?但是它对许多嵌套对象产生的行太长,而我对JavaScript修改映射函数的经验不足。

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>
javascript arrays nested traversal
1个回答
0
投票

简单的DFS或BFS算法应该在这里完成工作。区别在于创建的“行”的顺序。如果要在给定节点的所有子节点的父节点后立即列出所有子节点,则需要使用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)
© www.soinside.com 2019 - 2024. All rights reserved.