skip to Main Content

Need your help guys

I have nested object with infinity nesting.
How I can reorganize children keys to numeric keys?

From this:

{
  children: [
    {
      taskId: "e3f241f8-c879-4118-893d-a16715e45308",
      opts: {},
      children: [
        {
          taskId: "e3f241f8-c879-4118-893d-a248cae411208",
          opts: {},
          children: [
            taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
            opts: {},
            children: []
          ]
        }
      ],
    }
  ],
}

To this:

{
  1: {
    2: {
      3: {
        4: ''
      }
    }
  }
}

I’m trying use forEach and recursive function, but any result.

3

Answers


  1. const data = {
      children: [{
        taskId: "e3f241f8-c879-4118-893d-a16715e45308",
        opts: {},
        children: [{
          taskId: "e3f241f8-c879-4118-893d-a248cae411208",
          opts: {},
          children: [{
            taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
            opts: {},
            children: []
          }]
        }],
      }],
    }
    
    const result = replace(data)
    
    console.log(result)
    
    function replace(object, level = 1) {
      if (object !== undefined) {
        return {
          [level]: replace(object.children[0], level + 1)
        }
      }
      return ''
    }
    Login or Signup to reply.
  2. Not sure how much sense this explanation makes but… Here the idea is to loop through a queue that gets built as you go. The items in the queue being the old data object and a reference to a new one that’s being created as you go. A number gets incremented on each iteration to serve as the new key values. Each iteration a member of the queue gets removed and serves as the basis to add more items to the queue if the current object has children.

    The following numbers the items horizontally down the tree (or breadth-first / level-order traversal):

    const data = {
      children: [
        {
          taskId: "e3f241f8-c879-4118-893d-a16715e45308",
          opts: {},
          children: [
            {
              taskId: "e3f241f8-c879-4118-893d-a248cae411208",
              opts: {},
              children: [
                {
                  taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
                  opts: {},
                  children: []
                },
              ]
            },
            {
              taskId: "e3f241f8-c879-4118-893d-a248cae411208",
              opts: {},
              children: [
                {
                  taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
                  opts: {},
                  children: [
                    {
                      children: []
                    },
                    {
                      children: []
                    },
                  ]
                },
              ]
            },
          ],
        }
      ],
    };
    
    const get_numeric_keys = (data) => {
      let number = 0;
      const result = {};
      const queue = [[data, result]];
      
      while(queue.length > 0) {
        const [obj, new_obj] = queue.shift();
        
        number++;
        new_obj[number] = obj?.children?.length > 0 ? {} : '';
        
        if(obj?.children?.length > 0) {
          queue.push(...obj.children.map( (child) => [child, new_obj[number]] ));
        }
      }
      
      return result;
    };
    
    console.log(get_numeric_keys(data));

    This version numbers the items by going down as far as possible first (or depth-first traversal):

    const data = {
      children: [
        {
          taskId: "e3f241f8-c879-4118-893d-a16715e45308",
          opts: {},
          children: [
            {
              taskId: "e3f241f8-c879-4118-893d-a248cae411208",
              opts: {},
              children: [
                {
                  taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
                  opts: {},
                  children: []
                },
              ]
            },
            {
              taskId: "e3f241f8-c879-4118-893d-a248cae411208",
              opts: {},
              children: [
                {
                  taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
                  opts: {},
                  children: [
                    {
                      children: []
                    },
                    {
                      children: []
                    },
                  ]
                },
              ]
            },
          ],
        }
      ],
    };
    
    const get_numeric_keys = (data) => {
      let number = 0;
      const result = {};
      const queue = [[data, result]];
      
      while(queue.length > 0) {
        const [obj, new_obj] = queue.pop(); // pop instead of shift
        
        number++;
        new_obj[number] = obj?.children?.length > 0 ? {} : '';
        
        if(obj?.children?.length > 0) {
          // the new items go into the queue in reverse order here.
          queue.push(...obj.children.map( (child) => [child, new_obj[number]] ).reverse());
        }
      }
      
      return result;
    };
    
    console.log(get_numeric_keys(data));
    Login or Signup to reply.
  3. It seems to work:
    I am not sure why it works, but I’ve got some points (may help solving the problem):

    1. Determine when to stop recursion
    2. Thinking in TypeScript does help

    Note: I don’t understand what is your question here: what traversal ordering do you want? in BFS or DFS? I am answering in DFS now because you’ve mentioned "recursion".

    // type ObjType = { children: [] | ObjType[]; };
    const obj = {
      children: [
        {
          taskId: "e3f241f8-c879-4118-893d-a16715e45308",
          opts: {},
          children: [
            {
              taskId: "e3f241f8-c879-4118-893d-a248cae411208",
              opts: {},
              children: [
                { // [+] Curly Brackets
                  taskId: "e3f241f8-c879-4118-89112d-s248cae411208",
                  opts: {},
                  children: []
                },
                {
                  children: []
                }
              ]
            }
          ],
        },
        {
          children: [
            {
              children: []
            }
          ]
        }
      ],
    };
    
    // type MappedType = { [key: number]: string | MappedType; };
    // {
    //   1: {
    //     2: {
    //       3: {
    //         4: ""
    //       },
    //       5: {
    //         6: ""
    //       }
    //     }
    //   },
    //   7: {
    //     8: {
    //       9: ""
    //     }
    //   }
    // }
    
    
    // obj: ObjType, key is referenced
    const mapper = (obj, key = [0]) => {
      key[0] += 1;
      const children = obj.children;
      if (children.length === 0) {
        return { [key[0]++]: '' };
      }
    
      // mapped: MappedType
      const mapped = {};
      for (const child of obj.children) {
        mapped[key[0]] = mapper(child, key); // key[0] is modified after returning
      }
      return mapped;
    }
    
    console.log(JSON.stringify(mapper(obj), undefined, 2));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search