对象数组到多级树视图

array of objects to multilevel tree view

我有一个对象数组,如下所示:

[ { 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' } ]

我想将其重组为树状结构,其中最低级别或订单是父级,其余参数(如属、种和品系)分别相互嵌套。结构如下所示的示例树数据:

[
    {
      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'
    }
  ]

换句话说,我想要的输出如下所示:

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

有人可以给我一些建议来解决这个问题吗?

您可以先创建一个如下所示的嵌套对象结构:

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

然后将其转换为嵌套数组结构,方法是将 key/value 对转换为对象数组,使用 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);