如何将 objects 数组的树结构克隆到另一个数组,将属性更改为克隆?

How can I clone a tree structure of an array of objects to another one, changing attributes to the cloned?

如何将 objects 数组的树结构克隆到另一个数组,在 TypeScript 中对克隆的数组具有不同或更少的属性? 例如:

[
   {
      "name":"root_1",
      "extradata":"whatever",
      "anArray":[
         { "id":1, "value":"test" },
         { "id":1, "value":"test" }
      ],
      "anObject":{ "id":1, "value":"test" },
      "children":[
         {
            "name":"child_1",
            "extradata":"whatever",
            "anArray":[],
            "anObject":{},
            "children":[
               {
                  "name":"root_1",
                  "extradata":"whatever",
                  "anArray":[],
                  "anObject":{},
                  "children":[]
               },
               {
                  "name":"root_1",
                  "extradata":"whatever",
                  "anArray":[],
                  "anObject":{},
                  "children":[]
               }
            ]
         }
      ]
   },
   {
      "name":"root_2",
      "extradata":"whatever",
      "anArray":[],
      "anObject":{},
      "children":[]
   }
]

我需要它的克隆,但不是“命名”属性“标签”,而是“extradata”=“key”并且没有“anArray”和“anObject”。像这样:

[
   {
      "label":"root_1",
      "key":"whatever",
      "children":[
         {
            "label":"child_1",
            "key":"whatever",
            "children":[
               {
                  "label":"root_1",
                  "key":"whatever",
                  "children":[]
               },
               {
                  "label":"root_1",
                  "key":"whatever",
                  "children":[]
               }
            ]
         }
      ]
   },
   {
      "label":"root_2",
      "key":"whatever",
      "children":[]
   }
]

我需要克隆它,使用它作为 primeng 树组件的数据格式。

我正在尝试

this.myTree = tree.map((m, index) => Object.assign({}, {
                                label: m.name,
                                key: m.extradata,
                                children: m.children
                            }));

但是 children 不遵循相同的形状。

我不确定您是否可以使用第 3 方库 - 但您听说过 loadsh 吗? 有很多关于如何实现这一点的例子(:

first example

second example

如果你不能使用它,我会 dive 进入代码,看看他们是如何实现的 (:

我会通过首先为相关输入和输出类型定义接口来做到这一点:

interface InputTree {
  name: string,
  extradata: string,
  anArray: any[],
  anObject: object,
  children: InputTree[]
}

interface OutputTree {
  label: string,
  key: string,
  children: OutputTree[];
}

根据该定义,您的输入似乎是一个 InputTree[],而您想生成一个 OutputTree[]。树是递归的,因此您应该编写一个 treeMap() 函数,该函数在 InputTree[] 上运行,然后在数组中每个 InputTreechildren 上递归调用自身。像这样:

const treeMap = (inputTree: InputTree[]): OutputTree[] => inputTree.map(t => ({
  label: t.name,
  key: t.extradata,
  children: treeMap(t.children)
}));

const actual = treeMap(tree);

您可以验证这会产生您期望的输出:

console.log(JSON.stringify(expected)===JSON.stringify(actual)); // true

Playground link to code