Flat Array to Tree #2

by RichardAD

HTML

<title>Flat Array to Tree</title>
<!-- https://stackoverflow.com/questions/65523997/convert-flat-array-to-nested-array/65535543#65535543 -->

JavaScript

// Generic way

var input = [
    { Id: 1, LongName: "Europe;Germany;Frankfurt", Attribute1: "some attribute" },
    { Id: 2, LongName: "Europe;Germany;Munich", Attribute1: "some attribute" },
    { Id: 7, LongName: "Asia;Japan;Okinawa", Attribute1: "some attribute" },
    { Id: 8, LongName: "North America;US;Seattle", Attribute1: "some attribute" },
    { Id: 10, LongName: "Asia;China;Beijing", Attribute1: "some attribute" },
    { Id: 12, LongName: "Europe;France;Paris", Attribute1: "some attribute" },
    { Id: 14, LongName: "Europe;France;Marseille", Attribute1: "some attribute" },
    { Id: 5, LongName: "Asia;Japan;Tokyo", Attribute1: "some attribute" },
    { Id: 6, LongName: "Asia;Korea;Seoul", Attribute1: "some attribute" },
    { Id: 9, LongName: "Asia;Korea;Busan", Attribute1: "some attribute" },
    { Id: 11, LongName: "North America;US;New York", Attribute1: "some attribute" },
    { Id: 412, LongName: "North America;US;New York;County1", Attribute1: "some attribute" },
    { Id: 413, LongName: "North America;US;New York;County2", Attribute1: "some attribute" },
    { Id: 414, LongName: "North America;US;New York;County3", Attribute1: "some attribute" },
    { Id: 415, LongName: "North America;US;New York;County3", Attribute1: "some attribute" },
];

output = input.reduce((rootChildren, { LongName, ...attributes }) => { 
    const levelnames = LongName.split(';');
		const leafname = levelnames.pop();
    
    // descend the tree to the array containing the leafs. insert levels as needed
    const bottomChildren = levelnames.reduce( (children, levelName) => {
    
      let levelIndex = children.findIndex ( ({Name}) => Name === levelName);
      
      if (levelIndex === -1) { // add new level at end of children
      	levelIndex = children.push ({ Name: levelName, Children:[] }) - 1;
      } else
      if (!children[levelIndex].hasOwnProperty("Children")) {
      	children[levelIndex].Children = [];
      }
      
      return...