5

I'm having a JSON array with properties as id and parentActivityId.

$scope.data = [
    {
        id: 1,
        activityName: "Drilling",
        parentActivityId: 0,
        items: [
            {
                id: 2,
                activityName: "Blasting",
                parentActivityId: 1,
                items: [
                    {
                        id: 3,
                        activityName: "Ann",
                        parentActivityId: 2,
                        items: [],

                    },
                    {
                        id: 4,
                        activityName: "Ann",
                        parentActivityId: 2,
                        items: [],

                    }
                ]
            },
            {
                id: 5,
                activityName: "Transport",
                parentActivityId: 1,
                items: [
                    {
                        id: 6,
                        activityName: "Daniel",
                        parentActivityId: 5,
                        items: [],
                    }
                ]
            }
        ]
    }
];

I would like to push a new item based on the parentActiityId.The new item will be having a new id. Example:If my object is like this:

{
    id: 7,
    activityName: "Drilling",
    parentActivityId: 1,
    items: []
}

then my object will look like this..

 $scope.data = [
        {
            id: 1,
            activityName: "Drilling",
            parentActivityId: 0,
            items: [
                {
                    id: 2,
                    activityName: "Blasting",
                    parentActivityId: 1,
                    items: [
                        {
                            id: 3,
                            activityName: "Ann",
                            parentActivityId: 2,
                            items: [],

                        },
                        {
                            id: 4,
                            activityName: "Ann",
                            parentActivityId: 2,
                            items: [],

                        },
                    {
                         id: 7,
                         activityName: "Drilling",
                         parentActivityId: 2,
                         items: [],
                     }
                    ]
                },
                {
                    id: 5,
                    activityName: "Transport",
                    parentActivityId: 1,
                    items: [
                        {
                            id: 6,
                            activityName: "Daniel",
                            parentActivityId: 5,
                            items: [],
                        }
                    ]
                }
            ]
        }
    ];

I tried by giving this for loop..

var arrObj = {
    id: 7,
    activityName: "Drilling",
    parentActivityId: 1,
    items: []
};

function populateObj(arrObj) {
   for (var i = 0; i < $scope.data.length; i++) {
        if ($scope.data[i].id == arrObj.parentActivityId) {
            $scope.data.push(arrObj);
        }
    }
};

populateObj(arrObj);

which will push only to the parent.I want to identify the child as well in the for loop and the push to the specific array object by identifying thr parentActivityId.Any help will be really appreciated.

forgottofly
  • 2,729
  • 11
  • 51
  • 93

3 Answers3

6

With a recursive proposal and Array.prototype.reduce():

var data=[{id:1,activityName:"Drilling",parentActivityId:0,items:[{id:2,activityName:"Blasting",parentActivityId:1,items:[{id:3,activityName:"Ann",parentActivityId:2,items:[]},{id:4,activityName:"Ann",parentActivityId:2,items:[]}]},{id:5,activityName:"Transport",parentActivityId:1,items:[{id:6,activityName:"Daniel",parentActivityId:5,items:[]}]}]}],
    child = { id: 7, activityName: "Drilling", parentActivityId: 1, items: [] };

function getParent(r, a) {
    return a.id === child.parentActivityId ? a : a.items.reduce(getParent, r);
}

var node = data.reduce(getParent, {});
'items' in node && node.items.push(child);

document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
1983
  • 5,882
  • 2
  • 27
  • 39
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • If there is no data ie., data=[].I'm not able to add a new child element? – forgottofly Aug 19 '15 at 12:30
  • 1
    then you need `'if (items' in node) { node.items.push(child); } else { data.push(child); }`. but you have pay attention to the possible wrong `parentId`. – Nina Scholz Aug 19 '15 at 12:42
  • Thanks @Nina Scholz..Its working the way I need.Can you please explain your code.II'm not familiar with the reduce functionality.You can message me at mailmrmanoj@gmail.com – forgottofly Aug 19 '15 at 12:51
  • Also is there any way to get the total number of objects?Including the parent object – forgottofly Aug 19 '15 at 13:02
  • 1
    please have a look to [mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) they can better explain as i can. the total number of objects can counted with this small code :`function count(r, a) { return r + 1 + a.items.reduce(count, 0); } var nodeCount = data.reduce(count, 0);`. the `nodeCount` contains the number of nodes. – Nina Scholz Aug 19 '15 at 13:21
  • Awesome @Nina Scholz.Thanks a Ton!! – forgottofly Aug 19 '15 at 13:25
  • If I want to remove an object based on id from data will the same conditions apply?? – forgottofly Aug 20 '15 at 04:03
  • @forgottofly, then you have to iterate over the object with an other function. you may ask an other question at so. – Nina Scholz Aug 20 '15 at 20:05
  • please find the question here.http://stackoverflow.com/questions/32132222/deleting-an-object-based-on-the-id-in-javascript – forgottofly Aug 21 '15 at 04:10
2

You were close to what you tried to achieve. This should do the trick:

var arrObj = {
    id: 7,
    activityName: "Drilling",
    parentActivityId: 1,
    items: []
};

function populateObj(data, arrObj) {
   for (var i = 0; i < data.length; i++) {
        if (data[i].id == arrObj.parentActivityId) {
            data[i].items.push(arrObj);
        } else {
            populateObj(data[i].items, arrObj);
        }
    }
};

populateObj(arrObj);
Erazihel
  • 7,295
  • 6
  • 30
  • 53
  • I wanted to check the inner objects as well which I 'm not doing in if ($scope.data[i].id == arrObj.parentActivityId) .How to check if arrObj.parentActivityId exists inside the items array as well? – forgottofly Aug 19 '15 at 10:01
  • What it's the purpose of this check ? – Erazihel Aug 19 '15 at 10:36
  • If the parentActivityId is 7 then I have to check the objects inside items array as well – forgottofly Aug 19 '15 at 10:37
  • I don't understand where do you to push your new object. In the `items` array corresponding to the parentActivityId ? Why do you need to check the objects inside the `items` array? – Erazihel Aug 19 '15 at 10:47
  • If the parentActivityId is inside the items array I have to push inside items array – forgottofly Aug 19 '15 at 10:55
  • I've edited my code using recursive calls, it should be okay now – Erazihel Aug 19 '15 at 11:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/87370/discussion-between-forgottofly-and-erazihel). – forgottofly Aug 19 '15 at 11:15
0

To check the objects inside items array as well,you can do something like this,

var objectList = [
        {
            id: 1,
            activityName: "Drilling",
            parentActivityId: 0,
            items: [
                {
                    id: 2,
                    activityName: "Blasting",
                    parentActivityId: 1,
                    items: [
                        {
                            id: 3,
                            activityName: "Ann",
                            parentActivityId: 2,
                            items: [],

                        },
                        {
                            id: 4,
                            activityName: "Ann",
                            parentActivityId: 2,
                            items: [],

                        },
                    {
                         id: 7,
                         activityName: "Drilling",
                         parentActivityId: 2,
                         items: [],
                     }
                    ]
                },
                {
                    id: 5,
                    activityName: "Transport",
                    parentActivityId: 1,
                    items: [
                        {
                            id: 6,
                            activityName: "Daniel",
                            parentActivityId: 5,
                            items: [],
                        }
                    ]
                }
            ]
        }
    ];

var arrObj = {
    id: 7,
    activityName: "Drilling",
    parentActivityId: 1,
    items: []
};

function populateObj(ItemList) {
   for (var i = 0; i < ItemList.length; i++) {
        if (ItemList[i].id == arrObj.parentActivityId) {
            ItemList[i].items.push(arrObj);
        }
       else
       {
         populateObj(ItemList[i].items);
       }
    }
};

populateObj(objectList);
sp_m
  • 2,647
  • 8
  • 38
  • 62