unknownDev
unknownDev

Reputation: 31

Create nested object structure from flat one

If anyone can tell me please how can I do from this flat object structure:

mainObj = {
    "Ob1": {
        "id": 1,
        "name": "Ob1",
        "properties": {
            "attName": "A1",
            "attType": "string",
            "attOccurance": "minOccurs="1""
        },
    },
    "Ob2": {
         "id": 101,
         "name": "Ob2",
         "properties": {
             "attName": "B1",
             "attType": "string",
             "attOccurance": "minOccurs="1""
         },
     }
     "Ob3": {
          "id": 10001,
          "name": "Ob3",
          "properties": {
              "attName": "C1",
              "attType": "string",
              "attOccurance": "minOccurs="1""
              },
     }
}

To this one nested in another object, but with the data of the flat one:

myObj = {
    "Ob1": {
        "myObjName": "A1",
        "myObjType": "string",
        "myObjOcc": "minOccurs="1""
        "Ob2": {
            "myObjName": "B1",
            "myObjType": "string",
            "myObjOcc": "minOccurs="1""
            "Ob3": {
                "myObjName": "C1",
                "myObjType": "string",
                "myObjOcc": "minOccurs="1""
            } 
        }
   }
}

The nesting logic is, if the next object's id is bigger than the previous one, then is it's child. This is the logic:

for each(var obj in mainObj){
    switch (true) {
        case  obj.id < 100: levelId=1; break;
        case  obj.id < 10000: levelId=2; break;
        case  obj.id < 1000000: levelId=3; break;
        case  obj.id < 100000000: levelId=4; break;
    }
}

I have just this, but I don't know how to nest them:

for (key in mainObj) {
    myObj.myObjName = mainObj[key].properties.attName,
    myObj.myObjTyp = mainObj[key].properties.attType,
    myObj.myObjOcc = mainObj[key].properties.attOccurance
}

Please if anyone can tell me how can I do this?

Upvotes: 0

Views: 188

Answers (1)

Nitish Narang
Nitish Narang

Reputation: 4184

Given the input and output this is what I have come up with. See if it helps.

Though there were many cases I thought that I am not sure what the output should be.

const mainObj = {"Ob1": {    "id": 1,    "name": "Ob1",    "properties": {        "attName": "A1",        "attType": "string",        "attOccurance": "minOccurs='1'"    },},"Ob2": {     "id": 101,     "name": "Ob2",     "properties": {         "attName": "B1",         "attType": "string",         "attOccurance": "minOccurs='1'"     }, }, "Ob3": {      "id": 10001,      "name": "Ob3",      "properties": {          "attName": "C1",          "attType": "string",          "attOccurance": "minOccurs='1'"          }, }, "Ob4": {      "id": 202,      "name": "Ob4",      "properties": {          "attName": "D1",          "attType": "string",          "attOccurance": "minOccurs='1'"          }   }}

let levelKey = {}, newObj = {}

function getLevel(id) {
  let level = 1
  while(parseInt(id / 100) > 0) {
    level++
    id = id / 100
  }
  return level
}

function getLastLevel(id) {
  id--
  while(id > 0) {
    if(levelKey[id]) return id
    id--
  }
  return id
}

function getObj(str) {
  return str.split('.').reduce((o, d) => o[d], newObj)
}

for( let [k, v] of Object.entries(mainObj)) {
  let level = getLevel(v['id'])
  let obj = {
    myObjName: v.properties.attName,
    myObjType: v.properties.attType,
    myObjOcc: v.properties.attOccurance
  }

  let lastLevel = getLastLevel(level) || level
  levelKey[lastLevel]
    ? (getObj(levelKey[lastLevel])[k] = obj, levelKey[level] = levelKey[lastLevel] + '.' + k)
    : (newObj[k] = obj, levelKey[level] = k)
}

console.log(newObj)

Upvotes: 1

Related Questions