从非嵌套对象数组创建嵌套对象数组

时间:2016-07-28 11:05:21

标签: javascript arrays angularjs

假设我有以下数组:

[  
   {  
      '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
   }
]

我需要在角度控制器中编写一些javascript代码,或者在视图中使用ng-repeat来生成以下输出:

  [  
   {  
      '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
   },

]

您可以假设原始数组已按顺序排序,但输出也必须维护顺序。

我目前的解决方案确实有效。我使用带有条件参数的ng-repeat来检查当前对象是否有父对象。

基本上我使用ng-repeat输出所有父节点,然后我再次遍历整个数组,以便每个父节点检查子节点。这会导致严重的性能损失,并且对于长度超过40-50个对象的阵列而言需要太长时间。另一个缺点是,对于每个深度,性能损失都会增加。我想包括最多5个嵌套级别,但我的循环系统不会支持。

理想情况下,我会在控制器中对所有这些进行排序,然后使ng-repeat执行最少的工作。

有没有人真正阅读我目前的解决方案?在这里,因为我被指控免费获取物品 eye roll

<div class="comments">
        <span></span>
        <ul>
            <li class="comment byuser comment-author-solopine bypostauthor even 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>

正如我所说,使用ng-repeat。

1 个答案:

答案 0 :(得分:2)

您可以使用对象进行查找并插入父级的子级。加入节点本身。

此提案仅在父级插入子级之前有效。

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);

对未分类数据的提议保留了排序顺序。

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);