Home > Software design >  array of objects to multilevel tree view
array of objects to multilevel tree view

Time:05-25

I have an array of objects as shown below:

[ { strain: 'Nc14',
    species: 'Albugo laibachii',
    genus: 'Albugo',
    orders: 'Albuginales' },
  { strain: 'NZFS3378',
    species: 'Phytophthora multivora',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'NZFS3378',
    species: 'Phytophthora multivora',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'totara',
    species: 'Phytophthora taxon',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'ATCC12531',
    species: 'Pythium arrhenomanes',
    genus: 'Pythium',
    orders: 'Pythiales' },
  { strain: 'DAOMBR242034',
    species: 'Pythium iwayamai',
    genus: 'Pythium',
    orders: 'Pythiales' },
  { strain: 'DAOMBR444',
    species: 'Pythium aphanidermatum',
    genus: 'Pythium',
    orders: 'Pythiales' },
  { strain: 'DAOMBR484',
    species: 'Pythium vexans',
    genus: 'Phytopythium',
    orders: 'Peronosporales' },
  { strain: 'DAOMBR486',
    species: 'Pythium irregulare',
    genus: 'Pythium',
    orders: 'Pythiales' },
  { strain: 'var.sporangiiferumBR650',
    species: 'Pythium ultimum',
    genus: 'Pythium',
    orders: 'Pythiales' },
  { strain: 'INRA-310',
    species: 'Phytophthora parasitica',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'CBS223.65',
    species: 'Saprolegnia parasitica',
    genus: 'Saprolegnia',
    orders: 'Saprolegniales' },
  { strain: 'VS20',
    species: 'Saprolegnia diclina',
    genus: 'Saprolegnia',
    orders: 'Saprolegniales' },
  { strain: 'LT1534',
    species: 'Phytophthora capsici',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'Emoy2',
    species: 'Hyaloperonospora arabidopsidis',
    genus: 'Hyaloperonospora',
    orders: 'Peronosporales' },
  { strain: 'DAOMBR144',
    species: 'Pythium ultimum',
    genus: 'Pythium',
    orders: 'Pythiales' },
  { strain: 'T30-4',
    species: 'Phytophthora infestans',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'ND886',
    species: 'Phytophthora ramorum',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'pctg',
    species: 'Phytophthora ramorum',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'HapA',
    species: 'Phytophthora ramorum',
    genus: 'Phytophthora',
    orders: 'Peronosporales' },
  { strain: 'HapB',
    species: 'Phytophthora ramorum',
    genus: 'Phytophthora',
    orders: 'Peronosporales' } ]

I want to restructure this into a tree like structure where the lowest level or orders is the parent and the rest of the parameters like genus, species and strain are nested within each other respectively. Structure is like the sample tree data shown below:

[
    {
      key: 'mammal',
      label: 'Mammal',
      nodes: [
        {
          key: 'canidae',
          label: 'Canidae',
          nodes: [
            {
              key: 'dog',
              label: 'Dog',
              nodes: [],
              url: 'https://www.google.com/search?q=dog'
            },
            {
              key: 'fox',
              label: 'Fox',
              nodes: [],
              url: 'https://www.google.com/search?q=fox'
            },
            {
              key: 'wolf',
              label: 'Wolf',
              nodes: [],
              url: 'https://www.google.com/search?q=wolf'
            }
          ],
          url: 'https://www.google.com/search?q=canidae'
        }
      ],
      url: 'https://www.google.com/search?q=mammal'
    },
    {
      key: 'reptile',
      label: 'Reptile',
      nodes: [
        {
          key: 'squamata',
          label: 'Squamata',
          nodes: [
            {
              key: 'lizard',
              label: 'Lizard',
              url: 'https://www.google.com/search?q=lizard'
            },
            {
              key: 'snake',
              label: 'Snake',
              url: 'https://www.google.com/search?q=snake'
            },
            {
              key: 'gekko',
              label: 'Gekko',
              url: 'https://www.google.com/search?q=gekko'
            }
          ],
          url: 'https://www.google.com/search?q=squamata'
        }
      ],
      url: 'https://www.google.com/search?q=reptile'
    }
  ]

In other words the output I want looks like this:

[
    {
      key: 'Albuginales',
      label: 'Albuginales',
      nodes: [{
          key: 'Albugo',
          label: 'Albugo',
          nodes: [ 
...and so on recursively]
           url: ''
            }]
      url: ''} 
.
.
. ]      

Can somebody give me some suggestions to solve this?

CodePudding user response:

You could first create a nested object structure that looks like this:

{
  "Albuginales": {
    "Albugo": {
      "Albugo laibachii": {
        "Nc14": ""
      }
    }
  },
  "Peronosporales": {
    "Phytophthora": {
      "Phytophthora multivora": {
        "NZFS3378": ""
      },
      "Phytophthora taxon": {
        "totara": ""
      },
      //  ...etc

And then convert that to the nested array structure, by turning key/value pairs into an array of objects, using Object.entries:

const data = [ { strain: 'Nc14',species: 'Albugo laibachii',genus: 'Albugo',orders: 'Albuginales' },{ strain: 'NZFS3378',species: 'Phytophthora multivora',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'NZFS3378',species: 'Phytophthora multivora',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'totara',species: 'Phytophthora taxon',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'ATCC12531',species: 'Pythium arrhenomanes',genus: 'Pythium',orders: 'Pythiales' },{ strain: 'DAOMBR242034',species: 'Pythium iwayamai',genus: 'Pythium',orders: 'Pythiales' },{ strain: 'DAOMBR444',species: 'Pythium aphanidermatum',genus: 'Pythium',orders: 'Pythiales' },{ strain: 'DAOMBR484',species: 'Pythium vexans',genus: 'Phytopythium',orders: 'Peronosporales' },{ strain: 'DAOMBR486',species: 'Pythium irregulare',genus: 'Pythium',orders: 'Pythiales' },{ strain: 'var.sporangiiferumBR650',species: 'Pythium ultimum',genus: 'Pythium',orders: 'Pythiales' },{ strain: 'INRA-310',species: 'Phytophthora parasitica',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'CBS223.65',species: 'Saprolegnia parasitica',genus: 'Saprolegnia',orders: 'Saprolegniales' },{ strain: 'VS20',species: 'Saprolegnia diclina',genus: 'Saprolegnia',orders: 'Saprolegniales' },{ strain: 'LT1534',species: 'Phytophthora capsici',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'Emoy2',species: 'Hyaloperonospora arabidopsidis',genus: 'Hyaloperonospora',orders: 'Peronosporales' },{ strain: 'DAOMBR144',species: 'Pythium ultimum',genus: 'Pythium',orders: 'Pythiales' },{ strain: 'T30-4',species: 'Phytophthora infestans',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'ND886',species: 'Phytophthora ramorum',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'pctg',species: 'Phytophthora ramorum',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'HapA',species: 'Phytophthora ramorum',genus: 'Phytophthora',orders: 'Peronosporales' },{ strain: 'HapB',species: 'Phytophthora ramorum',genus: 'Phytophthora',orders: 'Peronosporales' } ];

// Create nested object structure
const tree = {};
for (let {strain, species, genus, orders} of data) {
    (((tree[orders ] ??= {})
           [genus  ] ??= {})
           [species] ??= {})
           [strain ]   = "";
}

// Convert to nested arrays
const toArray = tree => 
    Object.entries(tree).map(([label, url]) => ({
        key: label.toLowerCase().replaceAll(" ", "_"),
        label,
        ...(typeof url === "string" ? { url } : { nodes: toArray(url) })
    }));

const result = toArray(tree);
console.log(result);

  • Related