typescript 如何在js中获取深度嵌套数组的子数组

4urapxun  于 2023-05-19  发布在  TypeScript
关注(0)|答案(1)|浏览(281)

我有这个数据

const data = [
    {
      name: "Car",
      id: "19",
      count: "20",
      depth: "1",
      children: [
        {
          name: "Wheel",
          id: "22",
          count: "3",
          depth: "2",
          children: [
            {
              name: "Engine",
              id: "101",
              count: "1",
              depth: "3",
              children: [
                {
                  name: "Engine and Brakes",
                  id: "344",
                  count: "1",
                  depth: "4",
                  children: []
                }
              ]
            }
          ]
        }
      ]
    },
    {
      name: "Bike",
      id: "3",
      count: "12",
      depth: "1",
      children: [
        {
          name: "SpeedBike",
          id: "4",
          count: "12",
          depth: "2",
          children: []
        }
      ]
    }
  ];

我想传入多个类别id,如下所示['101','3'],并且只能得到传递的类别id的直接子项,应该是这样的:

[
  {
     name: "Engine and Brakes",
     id: "344",
     count: "1",
  },
  {
    name: "SpeedBike",
    id: "4",
    count: "12",
   }
]

如果没有传递类别id,我希望能够看到父项和直接子项作为默认值。如下所示:

[
 {  
    name: "Car",
    id: "19",
    count: "20"
 },
 {
    name: "Wheel",
    id: "22",
    count: "3"
 },
 {
    name: "Bike",
    id: "3",
    count: "12",
 },
 {
    name: "SpeedBike",
    id: "4",
    count: "12"
 }
]

如果传递的类别id没有子项,我希望返回一个空数组。:

[]

我想避免使用forforeachwhile。我如何才能做到这一点?我试过使用mapfilter,但没有运气。有人能帮帮忙吗最好的方法是什么?
我使用JS和TS。
嵌套数组可以是具有多个深度级别的深度数组。

yhived7q

yhived7q1#

没有内置函数可以做到这一点。相反,我们可以采取两种方法:迭代和递归。
递归方法需要O(logN)的额外空间用于调用堆栈大小;因此,我们将使用迭代方法。
算法:

  • 如果提供了类别ID:
  • 用第一级的类别填充堆栈
  • 当堆栈不为空时:
  • 从堆栈中弹出类别
  • 如果category id在所需的ids数组中:
  • Map类别的子项并检索所需的属性
  • 将类别的子项推入堆栈
  • 否则:
  • 循环通过第一级。
  • 推送父项和父项的子项。

类别类型:

type Category = {
  name: string;
  id: string;
  count: string;
  depth: string;
  children: Category[];
};

实施:

const getCategoriesChildren = (
  categoryIds: Category['id'][],
  categories: Category[],
) => {
  const foundChildren: Pick<Category, 'id' | 'count' | 'name'>[] = [];

  if (categoryIds.length === 0) {
    return categories.reduce<Pick<Category, 'id' | 'count' | 'name'>[]>(
      (acc, category) => {
        acc.push(mapCategory(category), ...category.children.map(mapCategory));
        return acc;
      },
      [],
    );
  }

  const stack = [...categories];

  while (stack.length) {
    const category = stack.pop();
    if (!category) continue;
    if (categoryIds.includes(category.id)) {
      foundChildren.push(
        ...category.children.map((childCategory) => ({
          name: childCategory.name,
          id: childCategory.id,
          count: childCategory.count,
        })),
      );
    }
    stack.push(...category.children);
  }

  return foundChildren;
};

使用方法:

// [{
//   "name": "SpeedBike",
//   "id": "4",
//   "count": "12"
// }, {
//   "name": "Engine and Brakes",
//   "id": "344",
//   "count": "1"
// }] 
console.log(getCategoriesChildren(['101', '3'], data));

// [{
//   "name": "Car",
//   "id": "19",
//   "count": "20"
// }, {
//   "name": "Wheel",
//   "id": "22",
//   "count": "3"
// }, {
//   "name": "Bike",
//   "id": "3",
//   "count": "12"
// }, {
//   "name": "SpeedBike",
//   "id": "4",
//   "count": "12"
// }]
console.log(getCategoriesChildren([], data));

playground

相关问题