TypeScript: оптимизировать вложенные для forEach () - PullRequest
1 голос
/ 28 апреля 2020

У меня есть вложенные данные с этим интерфейсом:

interface CategoryList {
  name: string;
  level: number;
  id: number;
  parentId: number;
  categoryList?: CategoryList[];
}

Так что внутри categoryList есть объект CategoryList, но с разными level от 3 до 6. Я хочу получать данные на каждом уровне и поворачивать данные должны быть похожи на следующий интерфейс:

interface NewCategoryList {
  name: string;
  level: number;
  id: number;
  parentId: number;
}

У меня есть это до сих пор, и он работал отлично, но безобразно:

function parseCategory(data: CategoryList, destination: NewCategoryList[]) {
  destination.push({
    id: data.id,
    name: data.name,
    level: data.level,
    parentId: data.parentId,
  });
}

function dataProcess(data: CategoryList[]) {
  //
  let data: NewCategoryList[] = [];
  //
  data.forEach((level_three) => {
    parseCategory(level_three, data);

    //
    if (level_three.categoryList) {
      level_three.categoryList.forEach((level_four) => {
        parseCategory(level_four, data);

        //
        if (level_four.categoryList) {
          level_four.categoryList.forEach((level_five) => {
            parseCategory(level_five, data);

            //
            if (level_five.categoryList) {
              level_five.categoryList.forEach((level_six) => {
                parseCategory(level_six, data);
              });
            }
          });
        }
      });
    }
  });

  writeFile(data, "data.json");
}

Как оптимизировать этот вложенный forEach()?

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Итак, у меня это работает до сих пор:

function dataProcess(data: CategoryList[]): NewCategoryList[] {
  const destination: NewCategoryList[] = [];

  (function loop(value: CategoryList[]) {
    for (const element of value) {
      // push element to the output array
      destination.push({
        id: element.id,
        name: element.name,
        level: element.level,
        parentId: element.parentId,
      });
      // check if element has child category list
      if (element.categoryList) {
        // loop recursively to this function again
        loop(element.categoryList);
      }
    }
  })(data);
  return destination;
}
0 голосов
/ 29 апреля 2020

Если у вас возникла рекурсивная проблема, начните с создания функции, которую вы ожидаете вызвать сама.

Код можно сделать чище, используя loda sh s pick и flatten

interface CategoryListItem {
    name: string;
    level: number;
    id: number;
    categoryList?: CategoryListItem[];
}

interface NewCategoryListItem {
    name: string;
    level: number;
    id: number;
    parentId?: number;
}

const root: CategoryListItem = {
    id: 1,
    name: '1',
    level: 1,
    categoryList: [
        {
            id: 2,
            name: '2',
            level: 2,
            categoryList: [
                {
                    id: 3,
                    name: '3',
                    level: 3,
                },
                {
                    id: 4,
                    name: '4',
                    level: 3,
                },
            ]
        }
    ]
};

function transform(item: CategoryListItem, parent?: NewCategoryListItem, level = 1): NewCategoryListItem[] {
    const newItem = {
        id: item.id,
        name: item.name,
        level,
        parentId: parent?.id,
    };

    const newChildren = item.categoryList?.map(child => transform(child, newItem, level + 1)) ?? [];
    const newChildrenFlat = ([] as NewCategoryListItem[]).concat(...newChildren);

    return [
        newItem,
        ...newChildrenFlat,
    ]
}

console.log(transform(root));

// 0: {id: 1, name: "1", level: 1, parentId: undefined}
// 1: {id: 2, name: "2", level: 2, parentId: 1}
// 2: {id: 3, name: "3", level: 3, parentId: 2}
// 3: { id: 4, name: "4", level: 3, parentId: 2 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...