javascriptreactjsarraysobjectarray-map

How to create an correct array structure based on a previous array of objects? JavaScript


hope you doing well. I have a question about how to clean up an array and make it a new one. I give you context, I have the following array:

const array = [
 { id: 1, parentId: null, name: Example },
 { id: 2, parentId: 1, name: Example },
 { id: 3, parentId: 1, name: Example },
 { id: 4, parentId: 1, name: Example },
 { id: 5, parentId: 2, name: Example },
 { id: 6, parentId: 2, name: Example },
 { id: 7, parentId: 6, name: Example },
 { id: 8, parentId: 7, name: Example },
 { id: 9, parentId: 7, name: Example },
];

I would like to know how I can convert it into an array structured in such a way that the first elements are the ones that are connected to the smallest parentId, in this case 1. And later, according to this value, new arrays are formed within its object. For example:

const array = [
 { id: 1, parentId: null, name: Example },
 { id: 2, parentId: 1, name: Example },
 { id: 3, parentId: 1, name: Example },
 { id: 4, parentId: 1, name: Example },
 { id: 5, parentId: 2, name: Example },
 { id: 6, parentId: 2, name: Example },
 { id: 7, parentId: 6, name: Example },
 { id: 8, parentId: 7, name: Example },
 { id: 9, parentId: 7, name: Example },
];

Into this:

const array = [
 { 
   id: 1, 
   parentId: null, 
   name: Example,
   options: [
    { 
      id: 2, 
      parentId: 1, 
      name: Example,
      options: [
       { id: 5, parentId: 2, name: Example },
       { id: 6, parentId: 2, name: Example },
      ]
    },
    { id: 3, parentId: 1, name: Example },
    { id: 4, parentId: 1, name: Example },
    { 
     id: 7, 
     parentId: 1, 
     name: Example,
     options: [
      { id: 8, parentId: 7, name: Example },
      { id: 9, parentId: 7, name: Example },
     ]
    },
   ]
 },
];

The array now sorts its options based on the parent id. Could anyone help me? I really find myself confused.

I tried using the map method, but its getting hard after some elements.


Solution

  • You can use a recursive function for this. The function assumes that the top-level items have parentId of null. If this is not the case, you may need to modify the function to pass in the top-level parentId value as an argument.

    function convertArray(arr, parentId = null) {
      const result = [];
      // We iterate over each item.
      for (const item of arr) {
        // If the item `parentId` matches the one received as parameter, 
        // this means the item is a child of the current parent node, 
        // and the function needs to recursively process its children.
        if (item.parentId === parentId) {
          // We copy the current item.
          const newItem = { ...item };
          // we call this function recursively with the `id` property of 
          // the current item as the new `parentId` parameter.
          // The results of the call is stored in the options property of `newItem`.
          // This creates a nested array of objects representing the child nodes.
          newItem.options = convertArray(arr, item.id);
          // We pushes newItem onto the result array.
          result.push(newItem);
        }
      }
      // Once all items in the input array have been processed, we return the result.
      return result;
    }
    
    const array = [
     { id: 1, parentId: null, name: 'Example' },
     { id: 2, parentId: 1, name: 'Example' },
     { id: 3, parentId: 1, name: 'Example' },
     { id: 4, parentId: 1, name: 'Example' },
     { id: 5, parentId: 2, name: 'Example' },
     { id: 6, parentId: 2, name: 'Example' },
     { id: 7, parentId: 6, name: 'Example' },
     { id: 8, parentId: 7, name: 'Example' },
     { id: 9, parentId: 7, name: 'Example' },
    ];
    console.log('Results for the array from your example: ', convertArray(array));

    I added comments in the snippets to explain what it does exactly.