javascript - Creating array of nested objects from array of non nested objects -
suppose have following array:
[ { 'id':48, 'parent':0, 'order':1 }, { 'id':49, 'parent':48, 'order':2 }, { 'id':50, 'parent':0, 'order':3 }, { 'id':51, 'parent':48, 'order':4 }, { 'id':52, 'parent':0, 'order':5 }, { 'id':53, 'parent':50, 'order':6 }, { 'id':54, 'parent':50, 'order':7 } ]
i need write javascript code either in angular controller or using ng-repeat in view can produce following output:
[ { 'id':48, 'parent':0, 'order':1, 'children':[ { 'id':49, 'parent':48, 'order':2 }, { 'id':51, 'parent':48, 'order':4 } ] }, { 'id':50, 'parent':0, 'order':3, 'children':[ { 'id':53, 'parent':50, 'order':6 }, { 'id':54, 'parent':50, 'order':7 } ] }, { 'id':52, 'parent':0, 'order':5 }, ]
you can assume original array sorted order already, output have maintain order well.
my current solution work. i'm using ng-repeat conditional argument check if current object has parent.
essentially i'm using ng-repeat output parents, loop through entire array again each parent checking children. has severe performance penalties , takes long array on 40-50 objects long. downside each depth, performance penalties increase. include 5 nesting levels, looping system not hold up.
ideally, sort out in controller, , make ng-repeat minimal work.
did read current solution? here is, since i'm being accused of getting things free eye roll
<div class="comments"> <span></span> <ul> <li class="comment byuser comment-author-solopine bypostauthor thread-even depth-1" id="comment-21"> <span></span> <div class="thecomment"> <span></span> <div class="author-img"> <span><img alt="" class="avatar avatar-60 photo" height="60" src="{{%20comment.author_avatar_urls['96']%20}}" width="60"></span> </div><span></span> <div class="comment-text"> <span><span class="reply"><a class="comment-reply-link scroll" href="" rel="nofollow">reply</a></span></span> <h6 class="author">{{ comment.author_name }}</h6><span class="date">{{ comment.date | date : 'longdate' }}</span> <p></p> <div></div> <p></p> </div> </div> </li> <li style="list-style: none"> <span></span> <ul class="children"> <li class="comment byuser comment-author-solopine bypostauthor odd alt depth-2" id="comment-24"> <span></span> <div class="thecomment"> <span></span> <div class="author-img"> <span><img alt="" class="avatar avatar-60 photo" height="60" src="{{%20childcomment.author_avatar_urls['96']%20}}" width="60"></span> </div><span></span> <div class="comment-text"> <span><span class="reply"><a class="comment-reply-link" href="" rel="nofollow">reply</a></span></span> <h6 class="author">{{ childcomment.author_name }}</h6><span class="date">{{ childcomment.date | date : 'longdate' }}</span> <p></p> <div></div> <p></p> </div> </div> </li><!-- #comment-## --> </ul><!-- .children --> <!-- #comment-## --> </li> </ul> </div>
as said, using ng-repeat.
you coud use object lookup , insert parent's children. adn node itself.
this proposal works if parent inserted before children.
var data = [{ 'id': 48, 'parent': 0, 'order': 1 }, { 'id': 49, 'parent': 48, 'order': 2 }, { 'id': 50, 'parent': 0, 'order': 3 }, { 'id': 51, 'parent': 48, 'order': 4 }, { 'id': 52, 'parent': 0, 'order': 5 }, { 'id': 53, 'parent': 50, 'order': 6 }, { 'id': 54, 'parent': 50, 'order': 7 }], tree = []; data.foreach(function (a) { this[a.id] = { id: a.id, parent: a.parent, order: a.order }; this[a.parent].children = this[a.parent].children || []; this[a.parent].children.push(this[a.id]); }, { 0: { children: tree } }); console.log(tree);
proposal unsorted data witch maintains sort order.
var data = [{ 'id': 54, 'parent': 50, 'order': 7 }, { 'id': 53, 'parent': 50, 'order': 6 }, { 'id': 49, 'parent': 48, 'order': 2 }, { 'id': 51, 'parent': 48, 'order': 4 }, { 'id': 52, 'parent': 0, 'order': 5 }, { 'id': 48, 'parent': 0, 'order': 1 }, { 'id': 50, 'parent': 0, 'order': 3 }, ], tree = function (data) { var r = [], o = { 0: { children: r } }; data.foreach(function (a) { var p = 0, temp = { id: a.id, parent: a.parent, order: a.order }; if (o[a.id] && o[a.id].children) { temp.children = o[a.id].children; } o[a.id] = temp; o[a.parent] = o[a.parent] || {}; o[a.parent].children = o[a.parent].children || []; o[a.parent].children.some(function (a) { if (a.order > temp.order) { return true; } p++; }); o[a.parent].children.splice(p, 0, temp); }); return r; }(data); console.log(tree);
Comments
Post a Comment