How does one convert a tree like nested data structure of arrays and objects into a list of items with computed/counted id’s and tracked parent id’s?

An API returns a nested data structure of arrays and objects. The data comes as a list of tree like objects, each with a possible parent-child relationship. The structure itself is shown by the following example code.

[{
  label: "search me",
  value: "searchme",
  children: [{

    label: "search me too",
    value: "searchmetoo",
    children: [{

      label: "No one can get me",
      value: "anonymous",
    }],
  }],
}, {
  label: "search me2",
  value: "searchme2",
  children: [{

    label: "search me too2",
    value: "searchmetoo2",
    children: [{

      label: "No one can get me2",
      value: "anonymous2",
    }],
  }],
}]

The above data has to be converted into a (flat) array of objects where each object will represent a former node element but with a unique primary key (id). Also a node’s parent-id equals its parent’s id (the primary key) except for root nodes that do not have a parent, and therefore the parent-id then should be null.

The target structure of the above provided source data then matches the following code …

[{
  id: 1,                // DIAGID
  parentId: null,       // PARENTID
  label: "search me",   // DIAGNOSIS
  value: "searchme"     // DIAGTYPE
}, {
  id: 2,
  parentId: 1,
  label: "search me too",
  value: "searchmetoo"
}, {
  id: 3,
  parentId: 2,
  label: "No one can get me",
  value: "anonymous"
}, {
  id: 4,
  parentId: null,
  label: "search me2",
  value: "searchme2"
}, {
  id: 5,
  parentId: 4,
  label: "search me too2",
  value: "searchmetoo2"
}, {
  id: 6,
  parentId: 5,
  label: "No one can get me2",
  value: "anonymous2"
}]

Answer

You could take a recursive method for Array#flatMap and store parent for the next call.

This approach increments id for all nodes.

const
    flatTree = (id => parent => ({ children = [], ...object }) => [
        { id: ++id, ...object, parent },
        ...children.flatMap(flatTree(id))
    ])(0),
    tree = [{ label: 'search me', value: 'searchme', children: [{ label: 'search me too', value: 'searchmetoo', children: [{ label: 'No one can get me', value: 'anonymous' }] }] }, { label: 'four', searchme: '4four' }],
    flat = tree.flatMap(flatTree(null));

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