使用c#中的嵌套回复对注释进行排序

时间:2017-02-26 21:30:40

标签: c#

如何使用嵌套回复对评论进行排序? 我的数据如下:

var comments = new List<Comment>();
comments.Add(AddNewComment(1, null, ""));
comments.Add(AddNewComment(2, null, ""));
comments.Add(AddNewComment(3, null, ""));
comments.Add(AddNewComment(4, 1, ""));
comments.Add(AddNewComment(5, 4, ""));
comments.Add(AddNewComment(6, 1, ""));
comments.Add(AddNewComment(7, null, ""));
comments.Add(AddNewComment(8, 7, ""));
comments.Add(AddNewComment(9, 8, ""));
comments.Add(AddNewComment(10, 9, ""));
comments.Add(AddNewComment(11, 2, ""));
comments.Add(AddNewComment(12, 11, ""));
comments.Add(AddNewComment(13, 1, ""));
comments.Add(AddNewComment(14, 13, ""));

public Comment AddNewComment(int id, int? replyId, string body)
{
    return new Comment
    {
        Id = id,
        ReplyId = replyId,
        Body = body
    };
}

public class Comment
{
    public int Id { get; set; }
    public int Depth { get; set; }
    public string Body { get; set; }
    public int? ReplyId { get; set; }
}

我希望得到类似的内容:

/* 
 * 1        =>Depth:0
 * -4       =>Depth:1
 * --5      =>Depth:2
 * -13      =>Depth:1
 * --14     =>Depth:2
 * -6       =>Depth:1
 * 2        =>Depth:0
 * -11      =>Depth:1
 * --12     =>Depth:2
 * 3        =>Depth:0
 * 7        =>Depth:0
 * -8       =>Depth:1
 * --9      =>Depth:2
 * ---10    =>Depth:3
 * */

我该怎么做?

2 个答案:

答案 0 :(得分:2)

要执行此操作,您需要创建分层排序算法。现在真正的问题是你希望它打印出来还是包含在以这种方式排序的另一个集合中。

首先,我修改了评论集合,以包含Comment属性中的子Children项。

public class Comment
{
    /// <summary>
    /// gets the child comments
    /// </summary>
    public IList<Comment> Children { get; } = new List<Comment>();

    public int Id { get; set; }
    public int Depth { get; set; }
    public string Body { get; set; }
    public int? ReplyId { get; set; }
}

现在使用与您相同的代码我创建了一个简单的枚举器系统,该系统可以为当前注释设计子代。这基于ReplyId具有值的位置和父级的ReplyId == Id。即。 Id:4 Maps as a child to Id:1

public static void EnumerateTree(Comment comment, int depth, IEnumerable<Comment> collection)
{
    comment.Depth = depth;
    foreach(var child in collection.Where(c => c.ReplyId.HasValue && c.ReplyId == comment.Id))
    {
        comment.Children.Add(child);
        EnumerateTree(child, depth + 1, collection);
    }
}

所以这是非常基本的,需要comment这是评论。深度是当前深度的基于0的索引。最后收集评论。这首先通过设置注释的深度来实现。然后,它会定位集合中映射到comment(父级)的所有子项。接下来迭代所有这些注释,将它们添加到父Children属性,然后调用该子项的EnumerateTree方法。

最后,我们将它放在您的主类中(在所有添加注释的内容下)。

var sorted = new List<Comment>();
foreach(var comment in comments.Where(x => x.ReplyId == null)) //root comments do not have a reply id
{
    sorted.Add(comment);
    EnumerateTree(comment, 0, comments);
}

最后,您将拥有基于层次结构的数据视图。

答案 1 :(得分:1)

您需要一个递归算法。请尝试以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Comment comment = new Comment();
            comment.Initialize();
            comment.SortComments();
            comment.PrintSortedComments();
        }
    }


    public class Comment
    {
        public static List<Comment> comments = new List<Comment>();
        public List<Comment> sortedComments = null;

        public int Id { get; set; }
        public int Depth { get; set; }
        public string Body { get; set; }
        public int? ReplyId { get; set; }

        public void Initialize()
        {
            comments.Add(AddNewComment(1, null, ""));
            comments.Add(AddNewComment(2, null, ""));
            comments.Add(AddNewComment(3, null, ""));
            comments.Add(AddNewComment(4, 1, ""));
            comments.Add(AddNewComment(5, 4, ""));
            comments.Add(AddNewComment(6, 1, ""));
            comments.Add(AddNewComment(7, null, ""));
            comments.Add(AddNewComment(8, 7, ""));
            comments.Add(AddNewComment(9, 8, ""));
            comments.Add(AddNewComment(10, 9, ""));
            comments.Add(AddNewComment(11, 2, ""));
            comments.Add(AddNewComment(12, 11, ""));
            comments.Add(AddNewComment(13, 1, ""));
            comments.Add(AddNewComment(14, 13, ""));
        }

        public Comment AddNewComment(int id, int? replyId, string body)
        {
            return new Comment
            {
                Id = id,
                ReplyId = replyId,
                Body = body
            };
        }
        public void SortComments()
        {
            sortedComments = new List<Comment>();

            List<Comment> levelZeroComments = comments.Where(x => x.ReplyId == null).OrderBy(x => x.Id).ToList();
            foreach (Comment comment in levelZeroComments)
            {
                sortedComments.Add(comment);
                comment.Depth = 0;
                RecusiveSort(comment.Id, 1);
            }
        }
        public void RecusiveSort(int id, int depth)
        {
            List<Comment> childComments = comments.Where(x => x.ReplyId == id).OrderBy(x => x.Id).ToList();

            foreach (Comment comment in childComments)
            {
                sortedComments.Add(comment);
                comment.Depth = depth;
                RecusiveSort(comment.Id, depth + 1);
            }

        }
        public void PrintSortedComments()
        {
            Console.WriteLine("/*");

            foreach (Comment sortComment in sortedComments)
            {
                Console.WriteLine(" * {0}{1}", new string('-', sortComment.Depth), sortComment.Id);
            }

            Console.WriteLine("* */");
            Console.ReadLine();
        }
    }
}