Home > Back-end >  Concentate values in a Nested Array of Object with children in JavaScript
Concentate values in a Nested Array of Object with children in JavaScript

Time:07-29

I have a nested array of objects having path as one of the keys. The structure of the nested array is as under:

const data = [
    {
        Name: "item1",
        path: "path1",
        children:[
            {
                Name: "item1.1",
                path: "path1.1"
            },
            {
                Name: "item1.2",
                path: "path1.2",
                children:[
                    {
                        Name: "item1.2.1",
                        path: "path1.2.1",
                        children:[
                            {
                                Name: "item1.2.1.1",
                                path: "path1.2.1.1"
                            }
                        ] 
                    },
                ]
            }
        ]
    }
]

I need to concentate the path values without changing the structure of array. The expected result would be:

const newdata: [
    {
        Name: "item1",
        path: "path1",
        children:[
            {
                Name: "item1.1",
                path: "path1/path1.1"
            },
            {
                Name: "item1.2",
                path: "path1/path1.2",
                children:[
                    {
                        Name: "item1.2.1",
                        path: "path1/path1.2/path1.2.1",
                        children:[
                            {
                                Name: "item1.2.1.1",
                                path: "path1/path1.2/path1.2.1/path1.2.1.1",
                            }
                        ] 
                    }
                ]
            }
        ]
    }
]

How to do it in JavaScript?

CodePudding user response:

This would be best done with a recursive Function, that iterates through your entire data structure and sets the Path by building it up while traversing your data structure.

The first version creates the path information from scratch, by using the index of each child in the array and building up the index that gets appended to the path string.

Further below i've provided changes to this version, that uses the already existing path information and concatenates the path string as you asked for.

// Recursive Function to iterate through a possible endless nested data structure
// We provide the parameter for the previous index and parentPath to build up the path string
function recursivePath(data, index = "", parentPath = "") {

  // We will get an Array with all Items as 'data' which we will loop with forEach
  data.forEach((item, i) => {

    // We recreate the the index of the item by adding current index of 
    // this item in the data array to the index structure of the parent items
    let itemIndex = index !== "" ? `${index}.${i 1}` : `${i 1}`;

    // We do the same for the path, we take the path of the parent 
    // and add the path information of this item to it.
    let itemPath = `${parentPath}path${itemIndex}`;

    // We set the path property of this item, which will be returned 
    // after all items of this data are done.
    item.path = itemPath;

    // We check if this item has some nested childrens and if it does, 
    // we will repeat this process for all those childrens
    if (item.children && typeof item.children.length) {

      // We provide the newly created index on which those childs will build upon 
      // as the same with the path.

      // This can be a bit confusing, but we assume here, that the function will return 
      //the finished childrens and we save the result to our childrens property.
      item.children = recursivePath(item.children, itemIndex, itemPath   "/");
    }
  });

  // Lastly we iterated through all Items and are sure to set the Path for all Items 
  // and their childrens nested inside and return the entire data array.
  return data;
}


// Your Data
const data = [{
  Name: "item1",
  path: "path1",
  children: [{
      Name: "item1.1",
      path: "path1.1"
    },
    {
      Name: "item1.2",
      path: "path1.2",
      children: [{
        Name: "item1.2.1",
        path: "path1.2.1",
        children: [{
          Name: "item1.2.1.1",
          path: "path1.2.1.1"
        }]
      }, ]
    }
  ]
}];

// We use the recursive function and output the results to the console
console.log(recursivePath(data));

If you would use the stored Path value of each item, you could just append the Value onto the parentPath String and save this new String into item.path

You would just change the line in the function, that creates the itemPath a little bit and you can remove the line that creates the itemIndex.

The parameter itemIndex of the recursive function isn't needed anymore and can be removed too.

// We wont need the index anymore, as we use the already existing 
// Path value for the Index of each item
function recursivePath(data, parentPath = "") {

  data.forEach((item, i) => {
  
    // We append the path information of this items path value
    // onto the parentPath string
    let itemPath = `${parentPath}${item.path}`;

    // Same as before
    item.path = itemPath;

    // Same as before
    if (item.children && typeof item.children.length) {
    
      // We removed the itemIndex, as it isnt needed anymore
      item.children = recursivePath(item.children, itemPath   "/");
    }
  });

  return data;
}


// Your Data
const data = [{
  Name: "item1",
  path: "path1",
  children: [{
      Name: "item1.1",
      path: "path1.1"
    },
    {
      Name: "item1.2",
      path: "path1.2",
      children: [{
        Name: "item1.2.1",
        path: "path1.2.1",
        children: [{
          Name: "item1.2.1.1",
          path: "path1.2.1.1"
        }]
      }, ]
    }
  ]
}];

// We use the recursive function and output the results to the console
console.log(recursivePath(data));

  • Related