Search code examples
javascriptlistrecursiontreeindentation

javascript : Create visible indentation by id - parentId relationship in flatList


I have a flatlist with hierarchy structure represented by ID parentID relationship like so:

[
      { id: "100", bezeichnung: "Node 1", parentId: null },
      { id: "101", bezeichnung: "Node 1 A", parentId: "100" },
      { id: "102", bezeichnung: "Node 1 B", parentId: "100" },
      { id: "200", bezeichnung: "Node 2", parentId: null },
      { id: "201", bezeichnung: "Node 2 A", parentId: "200" },
      { id: "202", bezeichnung: "Node 2 B", parentId: "200" },
      { id: "204", bezeichnung: "Node 2 BA", parentId: "202" },
      { id: "203", bezeichnung: "Node 3 A", parentId: "200" }
    ]

I like to translate this into something like this:

[
      { id: "100", bezeichnung: "Node 1", parentId: null, indent: 0 },
      { id: "101", bezeichnung: "Node 1 A", parentId: "100", indent: 1 },
      { id: "102", bezeichnung: "Node 1 B", parentId: "100", indent: 1 },
      { id: "200", bezeichnung: "Node 2", parentId: null, indent: 0 },
      { id: "201", bezeichnung: "Node 2 A", parentId: "200", indent: 1 },
      { id: "202", bezeichnung: "Node 2 B", parentId: "200", indent: 1 },
      { id: "204", bezeichnung: "Node 2 BA", parentId: "202", indent: 2 },
      { id: "203", bezeichnung: "Node 3 A", parentId: "200", indent: 1 }
    ]

note that the above shown Ids might be arbitrary uuids and not 0,100,200 etc.


Solution

  • So what you have is a list of nodes of a tree. Tree traversal is often most intuitively done using recursion:

    let input = [
        { id: "100", bezeichnung: "Node 1", parentId: null },
        { id: "101", bezeichnung: "Node 1 A", parentId: "100" },
        { id: "102", bezeichnung: "Node 1 B", parentId: "100" },
        { id: "200", bezeichnung: "Node 2", parentId: null },
        { id: "201", bezeichnung: "Node 2 A", parentId: "200" },
        { id: "202", bezeichnung: "Node 2 B", parentId: "200" },
        { id: "204", bezeichnung: "Node 2 BA", parentId: "202" },
        { id: "203", bezeichnung: "Node 3 A", parentId: "200" }
    ];
    
    input.forEach(element => element.indent = recursive(element,0))
    
    function recursive (element, i) {
        if (!element.parentId) return i;
        return recursive(input.find(parent => parent.id === element.parentId), i+1)
    }
    
    console.log(input)