Home > Back-end >  How to convert a method to recursive function in Javascript?
How to convert a method to recursive function in Javascript?

Time:06-18

I created a submenu from the first keys of the "res" data before the dot. In this submenu, I showed the keys with the same name in the "res" data only once. ie: "user", "department" and "project" appear as just a submenu item. But when I click on them, other keys with the same name do not appear once. For example: When I click on the "project" item, 5 "type" submenus are opened. And I need to do the same for the "id" key, too. How can I solve this?

var res = {
    "user.name.firstname": "firstname",
    "user.name.lastname": "lastname",
    "department.id1": 1,
    "department.id2": 2,
    "project.name": "project",
    "project.type.name": "project1",
    "project.type.id.first3": "321",
    "project.type.id.last3" : "789",
    "project.type.id.abc": "abc",

}
var myList = []
var myFinalList = []

Object.keys(res).forEach(key => {
    var subMenus = key.split(".")
    subMenus.forEach(subMenu => {
        var newObject = {}
        newObject["id"] = subMenu
        newObject["content"] = subMenu

        myList.push(newObject)
    })
    for (var i = myList.length - 1; i >= 0; i--) {
        if (i - 1 !== -1) {
            //console.log(i - 1)
            myList[i - 1]["submenu"] = [myList[i]]
        }
    }
    myFinalList.push(myList[0])
    //console.log(myList)
    myList = []
})
var mySet = new Set()
myFinalList.forEach(obj => {
    mySet.add(obj["id"])
})
    var veryFinalList = []
    mySet.forEach(key => {
        var eachKeyObject = myFinalList.filter(sub => sub.id === key)

        var sourceObject = eachKeyObject[0]
        if(eachKeyObject.length > 1){
            for(var i = 1; i < eachKeyObject.length; i  ){
                sourceObject["submenu"] = sourceObject["submenu"].concat(eachKeyObject[i]["submenu"])
            }
        }
        veryFinalList.push(sourceObject)
        console.log(veryFinalList)
    })

And my output should be like this:

output= {
    "user": {
        "name": {
            "firstname": "firstname",
            "lastname": "lastname",
        }
    },
    "department": {
        "id1":1,
        "id2":2,
    },
    "project": {
        "name": "project",
        "type": {
            "name": "project1",
            "id": {
                "first3": "321",
                "last3" : "789",
                "abc" : "abc"
            }
        }
    }
}

CodePudding user response:

Here you go:

var res = {
    "user.name.firstname": "firstname",
    "user.name.lastname": "lastname",
    "department.id1": 1,
    "department.id2": 2,
    "project.name": "project",
    "project.type.name": "project1",
    "project.type.id.first3": "321",
    "project.type.id.last3" : "789",
    "project.type.id.abc": "abc",

}

let finalObj = { };

for(let key in res) {
  let value = res[key];
  let keyArr = key.split('.');

  // Magic happens here (https://stackoverflow.com/a/68860247/2284136)
  keyArr.reduce((acc, key, i) => {
  
    if (i < keyArr.length - 1) {
      if (!acc[key]) acc[key] = {};
    } 
    else {
      acc[key] = value;
    }

    return acc[key];
  }, finalObj)
}

console.log(finalObj);

I used this answer for the reduce implementation, which allows us to put data deep into an object path. We just have to split the keys into and array first, like "user.name.firstname" => ["user", "name", "firstname"] and feed that to the reduce function with the value of res["user.name.firstname"].

Regarding your actual question about "converting a method to recursive function", I did try something like that at first, until I realized we don't need to do that here.

Also for a future reference, while recursive functions are great for some specific problems, the rule of thumb in general is to avoid having to use them if you don't absolutely have to. They are hard to read and understand, hard to debug and can lead to all kinds of wacky problems.

And regarding what you had tried to do to solve this. I think it's a great try and that is exactly what a great programmer should do when running into trouble! I love reading code like that because I can see the rabbit hole of frustration you were digging yourself into when trying to solve the problem. While it is indeed greatly frustrating, it also just as great learning experience. I personally think that when you find yourself from the bottom of that hole, still without a solution, that is the best time to ask for help, like you did!

  • Related