antonyboom
antonyboom

Reputation: 1181

recursively transform json object

I need help with recursively transform json object into another json object.

My input object looks like this:

var my_obj = {
  "id": 22,
  "eventTypeId": 37,
  "eventTypeName": "CommonOnly",
  "parentEvent": {
    "id": 21,
    "eventTypeId": 35,
    "eventTypeName": "FullTest",
    "parentEvent": {
      "id": 20,
      "parentEvent": null,
      "eventTypeId": 38,
      "eventTypeName": "FullTest"
    }
  },
  "childrenEvents": [
    {
      "id": 24,
      "parentEventId": 22,
      "eventTypeId": 36,
      "eventTypeName": "BlindedTest",
      "childrenEvents": []
    },
    {
      "id": 23,
      "parentEventId": 22,
      "eventTypeId": 38,
      "eventTypeName": "OneCustom",
      "childrenEvents": []
    }
  ]
}

The output I want is:

var my_obj = {
"id": 20,
"eventTypeId": 38,
"parentEvent": null,
"eventTypeName": "FullTest",
"childrenEvents": [{
    "id": 21,
    "eventTypeId": 35,
    "eventTypeName": "FullTest",
    "childrenEvents": [
        {
            "id": 22,
            "eventTypeId": 37,
            "eventTypeName": "CommonOnly",
            "childrenEvents": [
                {
                    "id": 24,
                    "parentEventId": 22,
                    "eventTypeId": 36,
                    "eventTypeName": "BlindedTest",
                    "childrenEvents": []
                }, {
                    "id": 23,
                    "parentEventId": 22,
                    "eventTypeId": 38,
                    "eventTypeName": "OneCustom",
                    "childrenEvents": []
                }
            ]
        }
    ]
}]

}

So I want to be able to get an object where the second parentEvent with parentEvent = null has became a root element, with an array childrenEvents, inside children array will be first parent event object with its own childrenEvents array and inside of this array I want to put existing root object with its own childrenEvents array

I appreciate if somebody could help me to resolve it. Thanks in advance.

My attempt

   function rebuild(input)
{
  var childrenEvents = [] ;

  for ( f in input.parentEvent )    // we may have attributes other than "age"
    if (f.parentEvent == null) {
        f.parentEvent.push(childrenEvents);
    } 
    else {
           f.parentEvent.push(input.parentEvent[f]);
    }

  if (input.childrenEvents.length !== 0)
    {
      input.parentEvent[f].push(input.childrenEvents)
    }

  return input;
}

    console.log(rebuild( $scope.myObj))

});

plunker

Upvotes: 0

Views: 142

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386654

You could use an object to build all dependencies and take only the one with

parentEvent === null

as tree.

var my_obj = { "id": 22, "eventTypeId": 37, "eventTypeName": "CommonOnly", "parentEvent": { "id": 21, "eventTypeId": 35, "eventTypeName": "FullTest", "parentEvent": { "id": 20, "parentEvent": null, "eventTypeId": 38, "eventTypeName": "FullTest" } }, "childrenEvents": [{ "id": 24, "parentEventId": 22, "eventTypeId": 36, "eventTypeName": "BlindedTest", "childrenEvents": [] }, { "id": 23, "parentEventId": 22, "eventTypeId": 38, "eventTypeName": "OneCustom", "childrenEvents": [] }] },
    tree = function (data, root) {
        function iter(a) {
            var parent;
            if (a.childrenEvents && Array.isArray(a.childrenEvents)) {
                a.childrenEvents.forEach(iter);
            }
            a.childrenEvents = o[a.id] && o[a.id].childrenEvents;
            o[a.id] = a;
            if (a.parentEvent === root) {
                r = a;
            } else {
                if (a.parentEvent && 'id' in a.parentEvent) {
                    parent = a.parentEvent.id;
                }
                if ('parentEventId' in a) {
                    parent = a.parentEventId;
                }
                if (parent !== undefined) {
                    o[parent] = o[parent] || {};
                    o[parent].childrenEvents = o[parent].childrenEvents || [];
                    o[parent].childrenEvents.push(a);
                }
            }
            if (a.parentEvent) {
                iter(a.parentEvent);
                delete a.parentEvent;
            }
        }

        var r, o = {};
        iter(data);
        return r;
    }(my_obj, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 3

Drew Wills
Drew Wills

Reputation: 8446

The title of your question says "recursively" but there is no recursion (that I can see) in your code. Yo need to call rebuild() from within rebuild()... recursively.

Maybe something closer to this (haven't run it)...

function rebuild(input) {

    var rslt = input;  // If it stays this way, we've reached the end of the line

    var parent = inpt.parentEvent;
    if (parent) {
        parent.childrenEvents = [];
        parent.childrenEvents.push(input);
        inpt.parentEventId = parent.id;
        rslt = rebuild(parent);
    }

    return rslt;

}

Upvotes: -1

Related Questions