Search code examples
javascriptarraystypescriptrecursiontail-recursion

Recursive iteration of an array


I have an array of classes:

const transferClasses = [
  {
    id: "c5d91430-aaab-ed11-8daf-85953743f5cc",
    name: "Class1",
    isTransfer: false,
    children: [],
  },
  {
    id: "775cb75d-aaab-ed11-8daf-85953743f5cc",
    name: "Class2",
    isTransfer: false,
    children: [
      {
        id: "89134f56-3ef6-ed11-8daf-85953743f5cc",
        name: "Class2-1",
        isTransfer: false,
        children: [],
      },
      {
        id: "89134f56-3ef6-ed11-8daf-85953743f4cc",
        name: "Class2-2",
        isTransfer: false,
        children: [
          {
            id: "89134f56-3ef6-ed11-8daf-85953743f4de",
            name: "Class2-2-1",
            isTransfer: false,
            children: [],
          },
          {
            id: "89134f56-3ef6-ed11-8daf-85953743f1ce",
            name: "Class2-2-2",
            isTransfer: false,
            children: [],
          },
        ],
      },
    ],
  },
];

I need to iterate over an array and turn it into a flat list. For expample:

const flatList = [
  {
    id: "c5d91430-aaab-ed11-8daf-85953743f5cc",
    name: "Class1",
    isTransfer: false,
    childrenId: null,
    parentId: null,
  },
  {
    id: "775cb75d-aaab-ed11-8daf-85953743f5cc",
    name: "Class2",
    isTransfer: false,
    childrenId: [
      "89134f56-3ef6-ed11-8daf-85953743f5cc",
      "89134f56-3ef6-ed11-8daf-85953743f4cc",
    ],
    parentId: null,
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f5cc",
    name: "Class2-1",
    isTransfer: false,
    childrenId: [],
    parentId: ["775cb75d-aaab-ed11-8daf-85953743f5cc"],
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f5cc",
    name: "Class2-2",
    isTransfer: false,
    childrenId: [
      "89134f56-3ef6-ed11-8daf-85953743f4de",
      "89134f56-3ef6-ed11-8daf-85953743f1ce",
    ],
    parentId: ["775cb75d-aaab-ed11-8daf-85953743f5cc"],
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f4de",
    name: "Class2-2-1",
    isTransfer: false,
    childrenId: [],
    parentId: ["89134f56-3ef6-ed11-8daf-85953743f5cc"],
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f1ce",
    name: "Class2-2-2",
    isTransfer: false,
    childrenId: [],
    parentId: ["89134f56-3ef6-ed11-8daf-85953743f5cc"],
  },
];

Each element needs to be given a list of id's of its parents and children.

Here is my function code. It seems I figured out what to do with the children, but there are no ideas at all how to add parents.

export const getFlatList = (classes) => {
  return classes.map((cl) => {
    
    const getChildIds = (classes) => {
      return classes.map((cl) => {
        if (cl.children.length > 0) {
          getChildIds(cl.children);
        } else {
          return cl.id;
        }
        return cl.id;
      });
    };

    return {
      id: cl.id,
      name: cl.name,
      isTransfer: cl.isTransfer,
      children: getChildIds(cl.children),
      parentId: ?? // :(
    };
  });
};

Solution

  • I came up with something like that. We start from the top and then look for children. If found, we go one level deeper until the children array is empty.

    const flattenArray = (array) => {
        let flatArray = [];
    
        const traverse = (node, parentId = null) => {
            const { children, ...restOfNode } = node;
    
            flatArray.push({
                ...restOfNode,
                childrenId: children ? children.map(child => child.id) : [],
                parentId: [parentId],
            });
    
            if (node.children.length) {
                node.children.forEach((child) => traverse(child, node.id));
            }
        }
    
        array.forEach((arrayItem) => traverse(arrayItem));
    
        return flatArray;
    }
    

    jsfidle: https://jsfiddle.net/wlecki/34cL8jh1/