Home > other >  Create a nested object with children from array of arrays
Create a nested object with children from array of arrays

Time:12-15

I have the following array of arrays

let arr = [
    [ "Female" , "Male" ],
    [ "Dinner" , "Lunch" ],
    [ "No" , "Yes" ],
]

I'd like to achieve this structure

let foo = [
    { 
        value: "Female",
        children: [
            {
                value: "Dinner",
                children: [
                    {
                        value: "No"
                    },
                    {
                        value: "Yes"
                    },
                ]
            },
            {
                value: "Lunch",
                children: [
                    {
                        value: "No"
                    },
                    {
                        value: "Yes"
                    },
                ]
             },
        ]
    },
    { 
        value: "Male",
        children: [
            {
                value: "Dinner",
                children: [
                    {
                        value: "No"
                    },
                    {
                        value: "Yes"
                    },
                ]
            },
            {
                value: "Lunch",
                children: [
                    {
                        value: "No"
                    },
                    {
                        value: "Yes"
                    },
                ]
             },
        ]
    },
]

I simply can't wrap my head around the problem to achieve this, thus, I don't have a starting code to post, so please if you can help, it would be great.

CodePudding user response:

You can also do it without recursion with 2 for

let arr = [
    [ "Female" , "Male" ],
    [ "Dinner" , "Lunch" ],
    [ "No" , "Yes" ],
];

var lastChild = -1;

for(var i = arr.length-1; i >= 0; i--) {
  var item = arr[i];
  var lastChildTemp = [];
  for(var j = 0; j < item.length; j  ) {
    var newChild = {value: item[j]};
    if(lastChild != -1) {
      newChild.children = lastChild;
    }
    lastChildTemp.push(newChild);
  }
  lastChild = lastChildTemp;
}

console.log(JSON.stringify(lastChildTemp,null,2));

Output:

[
  {
    "value": "Female",
    "children": [
      {
        "value": "Dinner",
        "children": [
          {
            "value": "No"
          },
          {
            "value": "Yes"
          }
        ]
      },
      {
        "value": "Lunch",
        "children": [
          {
            "value": "No"
          },
          {
            "value": "Yes"
          }
        ]
      }
    ]
  },
  {
    "value": "Male",
    "children": [
      {
        "value": "Dinner",
        "children": [
          {
            "value": "No"
          },
          {
            "value": "Yes"
          }
        ]
      },
      {
        "value": "Lunch",
        "children": [
          {
            "value": "No"
          },
          {
            "value": "Yes"
          }
        ]
      }
    ]
  }
]

The key here is to use backward for (starting from high index to low index), then create a lastChild object. Then put it in .children attribute of each next objects.

CodePudding user response:

You can try this:

let arr = [
  ['Female', 'Male'],
  ['Dinner', 'Lunch'],
  ['No', 'Yes']
]

function makeTree(a, ch = [], currIndex = 0) {
  for (const item of a[currIndex]) {

    if (a[currIndex   1]) {
      // If there is an array after this one then 
      // include the 'children' array
      const obj = { value: item, children: [] }
      ch.push(obj)

      // Run the function again to fill the `children` 
      // array with the values of the next array
      makeTree(a, obj.children, currIndex   1)

    } else {
      // If this is the last array then
      // just include the value 
      ch.push({ value: item })
    }
  }

  return ch
}

const result = makeTree(arr)
console.log(JSON.stringify(result, null, 2))
.as-console-wrapper { min-height: 100% }

CodePudding user response:

Checkout this code snippet. It outputs as per your need.

let arr = [
    [ "Female" , "Male" ],
    [ "Dinner" , "Lunch" ],
    [ "No" , "Yes" ],
]

let foo = [];


let arr2 = [];
arr[2].forEach(yn => {  
    arr2.push({ "value": yn});
});

let arr1 = [];
arr[1].forEach(dl => {
    arr1.push({
        "value": dl,
        "children": arr2
    }); 
});

arr[0].forEach(fm => {
    foo.push({
        "value": fm,
        "children": arr1
    }); 
});     

console.log(JSON.stringify(foo, null, 2))

CodePudding user response:

Rearrange your Array using the below code, then iterate as your wish and this is dynamic. you can have more rows in arr variable.

let arr = [
 [ "Female" , "Male" ],
 [ "Dinner" , "Lunch" ],
 [ "No" , "Yes" ],
] 
let finalArray = [];
for(let i=arr.length-2; i>-1; i--){
  for(let j=0; j< arr[i].length; j  ) {
    item = {}
    item[arr[i][j]] = arr[i 1];
    arr[i][j] = [];
    arr[i][j] = item;
  }
arr.pop();
}
console.log(arr);
/*output*/
[
[{
    'Female': [{
        'Dinner': ['No', 'Yes']
    }, {
        'Lunch': ['No', 'Yes']
    }]
}, {
    'Male': [{
        'Dinner': ['No', 'Yes']
    }, {
        'Lunch': ['No', 'Yes']
    }]
  }]
]

https://jsfiddle.net/Frangly/ywsL0pbt/147/

  • Related