Search code examples
javascriptarraysnested-object

Converting given structure two-dimensional array into array of nested objects


I have a sorted two-dimensional array as an input. I need to get an array of nested objects in the same structure as shown below. How do I get an expected output?

input = [
["1", "2", "3", "4", "5", "6", "7", "8"],
["1", "2", "3", "4", "5", "6", "7", "9"],
["cat", "accessories", "clothes"],
["cat", "food", "dry"],
["cat", "food", "wet"],
["dog", "drinks"],
["dog", "food"]];

This is what i tried:

var output = [];    
input.forEach((v, i) => {    
if (i !== 0){
    var temp_obj = {};

    for(let j=0; j<v.length; j++){
        if (input[i-1][j] === v[j]){
            temp_obj[input[i-1][j]] = [];
        }else if (!_.isEmpty(temp_obj) && typeof(input[i-1][j]) !== 'undefined'){
            console.log('this is it ', temp_obj)
        }
    }
    if (!_.isEmpty(temp_obj)){
        output.push(temp_obj);
    }
}
})

console.log(output)    

expected output

   output = [{
        "1": [{
            "2": [{
                "3": [{
                    "4": [{
                        "5": [{
                            "6": [{
                                "7": [{
                                    "8": []
                                }, {
                                    "9": []
                                }]
                            }]
                        }]
                    }]
                }]
            }]
        }]
    },
    {
        "cat": [{
            "accessories": [{
                "clothes": []
            }]
        }, {
            "food": [{
                "dry": []
            }, {
                "wet": []
            }]
        }]
    },
    {
        "dog": [{
            "food": []
        }, {
            "drinks": []
        }]
    }
]

Solution

  • Reduce is your friend

    input = [
      ["1", "2", "3", "4", "5", "6", "7", "8"],
      ["1", "2", "3", "4", "5", "6", "7", "9"],
      ["cat", "accessories", "clothes"],
      ["cat", "food", "dry"],
      ["cat", "food", "wet"],
      ["dog", "drinks"],
      ["dog", "food"]
    ];
    
    const structure = input.reduce((obj, arr) => {
      const last = arr.pop()
      const chain = arr.reduce((o, key) => {
        o[key] = o[key] || {}
        return o[key]
      }, obj)
      chain[last] = []
      return obj
    }, {})
    
    //console.log(structure)
    var finalArray = Object.entries(structure).map(
      ([k,v]) => ({[k]:v})
    )
    console.log(finalArray)