将具有嵌套数组的数组投影/缩减为给定格式

Project / reduce an array with nested arrays to a given format

我正在努力寻找一种方法来 project/reduce 基于显示 Angular Material 树视图的格式的数组。我的数据结构如下:

let data = [
  {
    section_name: "section one",
    blocks: [
      {
        block_name: "block one"
      },
      {
        block_name: "block two"
      }
    ],
    sections: []
  },
  {
    section_name: "section two",
    blocks: [
      {
        block_name: "block three"
      }
    ],
    sections: [
      {
        section_name: "subsection1",
        blocks: [
          {
            block_name: "subsection1 block1"
          }
        ],
        sections: []
      },
      {
        section_name: "subsection2",
        blocks: [
          {
            block_name: "subsection2 block1",
          },
          {
            block_name: "subsection2 block2",
          }
        ],
        sections: []
      }
    ]
  }
]

应该按照下面的格式进行整形。所以基本上上面数组中的每个外部对象都是一个部分,每个部分可能有块和子部分。每个块名称必须作为名称为 属性 的对象插入到子数组中,但对于子部分,我们需要检查是否有其他嵌套子部分(递归)。

[
  {
    "name": "section one",
    "children": [
      {
        "name": "block one"
      },
      {
        "name": "block two"
      }
    ]
  },
  {
    "name": "section two",
    "children": [
      {
        "name": "block three"
      },
      {
        "name": "subsection1",
        "children": [
          {
            "name": "subsection1 block1"
          }
        ]
      },
      {
        "name": "subsection2",
        "children": [
          {
            "name": "subsection2 block1"
          },
          {
            "name": "subsection2 block2"
          }
        ]
      }
    ]
  }
]

这可以通过相当简单的递归来管理。唯一的复杂性是您希望将处理 blocks 的结果和处理 sections 的结果合并到一个 children 节点中。我们只是通过将每个结果分散到一个数组中来做到这一点:

const convert = (records) =>
  records .map (({section_name, blocks, sections}) => ({
    name: section_name,
    children: [
      ... blocks .map (({block_name}) => ({name: block_name})),
      ... convert (sections)
    ]
  }))

const data = [{section_name: "section one", blocks: [{block_name: "block one"}, {block_name: "block two"}], sections: []}, {section_name: "section two", blocks: [{block_name: "block three"}], sections: [{section_name: "subsection1", blocks: [{block_name: "subsection1 block1"}], sections: []}, {section_name: "subsection2", blocks: [{block_name: "subsection2 block1"}, {block_name: "subsection2 block2"}], sections: []}]}]

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