评论数组快速归类的方法

2017-06-24 18:29:26 +08:00
 hoythan

我有一批评论,他们的格式类似

[
    {
    	commentID:1,
        comment_parentID:0
    },
   {
    	commentID:2,
        comment_parentID:1
    },
   {
    	commentID:3,
        comment_parentID:0
    },
   {
    	commentID:4,
        comment_parentID:2
    },
   {
    	commentID:5,
        comment_parentID:1
    }
]

所有层级的评论都被平铺开来为一层,现在我要变为多层的

[
    {
        commentID:1,
        comments:[
            {
                commentID:2,
                comment_parentID:1,
                comments:[
                    {
                        commentID:4,
                        comment_parentID:2
                    },
                 ]
            },
            {
                commentID:5,
                comment_parentID:1
            }
        ]
        
    },
    {
    	commentID:3,
        comment_parentID:0
    }
]

如何循环才能最快,他们的顺序不一定是正序到倒叙,是有可能乱的. ID 是唯一的.

1163 次点击
所在节点    问与答
8 条回复
lhx2008
2017-06-24 18:39:44 +08:00
标题有歧义啊
chairuosen
2017-06-24 18:45:45 +08:00
先写个 map id=>obj 方便查找
然后遍历原始数据每一项如果有父级找到父级对象塞 children 里,然后再把根节点拎出来排个序就行
大概是两遍循环
hoythan
2017-06-24 18:55:38 +08:00
@chairuosen 他有多层
cuebyte
2017-06-24 18:56:02 +08:00
双向链表,由子找父
hoythan
2017-06-24 20:05:32 +08:00
@cuebyte 不懂...求教育
geelaw
2017-06-24 20:17:24 +08:00
/* in-place, destructive */
function treefy(inputArray)
{
var outputArray = [];
inputArray.forEach(function (comment) { comment.comments = []; });
inputArray.sort(function (a, b) { return a.commentID - b.commentID; });
var helper = function (begin, end, n)
{
if (begin >= end) return null;
var mid = (begin + end) >> 1;
var testee = outputArray[mid].commentID;
return testee < n ? helper(begin, mid, n) : testee > n ? helper(mid + 1, end, n) : outputArray[mid];
};
inputArray.forEach(function (comment)
{
if (comment.comment_parentID == 0) outputArray.push(comment);
else helper(0, inputArray.length, comment.comment_parentID).comments.push(comment);
});
return outputArray;
}

没有测试过, provided as-is.
geelaw
2017-06-24 20:19:38 +08:00
@geelaw 果然写错了,二分查找的部分应该是 inputArray。另外实际上可以用 sparse array 来做这件事情,不需要二分查找。
cuebyte
2017-06-25 13:28:53 +08:00
@hoythan 不知道为什么你 at 我我没看到,就是字面意思啊。

首先对评论排序,方便之后的二分查找。遍历列表,取出一个评论就找它的父评论,再由父评论找父父评论,都存到双向列表里,直到没有父评论,结束,再继续从评论列表里取。

等评论列表空了之后,就找那些顶级评论(root),遍历其子评论树。最后得到你想要的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/370811

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX