如何展平对象的嵌套数组

时间:2019-07-31 09:32:59

标签: javascript

我有这个数据结构:

const contents: Contents = [
  {
    id: 'id_01',
    title: 'title_01',
    children: [
      {
        id: 'id_02',
        title: 'title_02',
        children: [
          {
            id: 'id_03',
            title: 'title_03',
          },
          {
            id: 'id_04',
            title: 'title_04',
          },
          {
            id: 'id_05',
            title: 'title_05',
          },
          {
            id: 'id_06',
            title: 'title_06',
          },
          {
            id: 'id_07',
            title: 'title_07',
          },
        ],
      },
      {
        id: 'id_08',
        title: 'title_08',
        children: [
          {
            id: 'id_09
            title: 'title_09
          },
          {
            id: 'id_10
            title: 'title_10
          },
          {
            id: 'id_11
            title: 'title_11
          },
        ],
      },
    ],
  },
  {
    id: 'id_12',
    title: 'title_12',
    children: [
      {
        id: 'id_13',
        title: 'title_13',
        children: [
          {
            id: 'id_14',
            title: 'title_14',
          },
          {
            id: 'id_05',
            title: 'title_15',
          },
        ],
      },
      {
        id: 'id_16',
        title: 'title_16',
        children: [
          {
            id: 'id_17',
            title: 'title_17',
          },
        ],
      },
    ],
  },
]

所以Content类型是:

export type Item = {
  id: string
  title: string
  children?: Item[]
}

export type Contents = Item[]

如何获得统一的数据结构?像这样:

[
  {
    id: 'id_01',
    title: 'title_01',
    children: [
      {
        id: 'id_02',
        title: 'title_02',
        children: [
          {
            id: 'id_03',
            title: 'title_03',
          },
          {
            id: 'id_04',
            title: 'title_04',
          },
          {
            id: 'id_05',
            title: 'title_05',
          },
          {
            id: 'id_06',
            title: 'title_06',
          },
          {
            id: 'id_07',
            title: 'title_07',
          },
        ],
      },
      {
        id: 'id_08',
        title: 'title_08',
        children: [
          {
            id: 'id_09
            title: 'title_09
          },
          {
            id: 'id_10
            title: 'title_10
          },
          {
            id: 'id_11
            title: 'title_11
          },
        ],
      },
    ],
  },
  {
    id: 'id_12',
    title: 'title_12',
    children: [
      {
        id: 'id_13',
        title: 'title_13',
        children: [
          {
            id: 'id_14',
            title: 'title_14',
          },
          {
            id: 'id_05',
            title: 'title_15',
          },
        ],
      },
      {
        id: 'id_16',
        title: 'title_16',
        children: [
          {
            id: 'id_17',
            title: 'title_17',
          },
        ],
      },
    ],
  },
  {
    id: 'id_02',
    title: 'title_02',
    children: [
      {
        id: 'id_03',
        title: 'title_03',
      },
      {
        id: 'id_04',
        title: 'title_04',
      },
      {
        id: 'id_05',
        title: 'title_05',
      },
      {
        id: 'id_06',
        title: 'title_06',
      },
      {
        id: 'id_07',
        title: 'title_07',
      },
    ],
  },
  {
    id: 'id_03',
    title: 'title_03',
  },
  {
    id: 'id_04',
    title: 'title_04',
  },
  {
    id: 'id_05',
    title: 'title_05',
  },
  {
    id: 'id_06',
    title: 'title_06',
  },
  {
    id: 'id_07',
    title: 'title_07',
  },
  {
    id: 'id_08',
    title: 'title_08',
    children: [
      {
        id: 'id_09
        title: 'title_09
      },
      {
        id: 'id_10
        title: 'title_10
      },
      {
        id: 'id_11
        title: 'title_11
      },
    ],
  },
  {
    id: 'id_09
    title: 'title_09
  },
  {
    id: 'id_10
    title: 'title_10
  },
  {
    id: 'id_11
    title: 'title_11
  },
  {
    id: 'id_12',
    title: 'title_12',
    children: [
      {
        id: 'id_13',
        title: 'title_13',
        children: [
          {
            id: 'id_14',
            title: 'title_14',
          },
          {
            id: 'id_05',
            title: 'title_15',
          },
        ],
      },
      {
        id: 'id_16',
        title: 'title_16',
        children: [
          {
            id: 'id_17',
            title: 'title_17',
          },
        ],
      },
    ],
  },
  {
    id: 'id_13',
    title: 'title_13',
    children: [
      {
        id: 'id_14',
        title: 'title_14',
      },
      {
        id: 'id_05',
        title: 'title_15',
      },
    ],
  },
  {
    id: 'id_17',
    title: 'title_17',
  },
]

我做一个简单的例子:

[
  {
    id: 1,
    children: [
      {
        id: 3,
        children: [
          {
            id: 4
          },
          {
            id: 5
          }
        ]
      }
    ]
  }, 
  {
    id: 2,
  }
]

应成为:

[
  {
    id: 1,
    children: [
      {
        id: 3,
        children: [
          {
            id: 4
          },
          {
            id: 5
          }
        ]
      }
    ]
  }, 
  {
    id: 2,
  },
  {
    id: 3,
    children: [
      {
        id: 4
      },
      {
        id: 5
      }
    ]
  },
  {
    id: 4
  },
  {
    id: 5
  }
]

我尝试了Lodash的flattenflattedDeep,但是没有用。

我尝试:

const flattenItems = flatten(contents)
const flattenItems = flattenDeep(contents)

在每种情况下,结果仅包含第一级的项目,因此对象为id_01id_12

结构可能会改变,我不知道深度的数量,所以我想拥有一个聪明的功能。 谢谢

1 个答案:

答案 0 :(得分:-1)

好像可以用一些recursion来解决。

function recursiveFlat(parent, child) {
    if(child.children && child.children.length > 0) {
        child.children.forEach(element => {
            parent.push(element);
            recursiveFlat(parent,element);
        });
    }
}

// Function used to order the tree.
function compare(a, b) {
  if (a.id < b.id) {
    return -1;
  }
  if (a.id > b.id) {
    return 1;
  }
  return 0;
}

// The code using it all.
contents.forEach(elem => {
    recursiveFlat(contents,elem);
    contents.sort(compare); // If you want to order the result by id
});

这是使用本示例和最后一个示例的结果:

[
  {
    "id": 1,
    "children": [
      {
        "id": 3,
        "children": [
          {
            "id": 4
          },
          {
            "id": 5
          }
        ]
      }
    ]
  },
  {
    "id": 2
  },
  {
    "id": 3,
    "children": [
      {
        "id": 4
      },
      {
        "id": 5
      }
    ]
  },
  {
    "id": 4
  },
  {
    "id": 5
  }
]