简体   繁体   English

使用C#中的嵌套回复对评论进行排序

[英]Sorting comments with nested replies in c#

How do I sort my comments with nested replies? 如何使用嵌套回复对评论进行排序? My data looks like: 我的数据如下:

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

I want to get something like: 我想得到类似的东西:

/* 
 * 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
 * */

How can I do this? 我怎样才能做到这一点?

To do this you will need to create a hierarchical sorting algorithm. 为此,您将需要创建一个分层的排序算法。 Now the real question is do you want it to print that or be contained in another collection that is sorted in that fashion. 现在,真正的问题是您是否要打印它或将其包含在以这种方式排序的另一个集合中。

First I modified the comment collection to contain child Comment items in the Children property. 首先,我修改了注释集合以在Children属性中包含子Comment项目。

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

Now using the same code as you I have created a simple enumerator system which works out the children for the current comment. 现在,使用与您相同的代码,我创建了一个简单的枚举器系统,该系统可以为当前注释创建子级。 This is based on where ReplyId has a value and ReplyId == Id for the parent. 这是基于ReplyId的值和父代的ReplyId == Id的位置。 ie. 即。 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);
    }
}

So this is pretty basic, takes a comment which is the parent comment. 所以这是非常基本的,需要一个comment ,即注释。 A depth which is a 0 based index of the current depth. 深度是当前深度的从0开始的索引。 And finally the collection of comments. 最后收集评论。 This works by first setting the depth to the comment. 这是通过首先设置评论的深度来实现的。 It then locates all the children in the collection that map to the comment (parent). 然后,它将找到映射到该comment所有子项(父项)。 Next iterates all of these comments adding them to the parent Children property and then recalls the EnumerateTree method for the child. 接下来,迭代所有这些注释,将其添加到父级Children属性中,然后为该子级调用EnumerateTree方法。

Finally we place this in your main class (under all your add comment stuff). 最后,我们将其放置在您的主类中(在所有添加注释的内容下)。

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

In the end you will have a hierarchical based view of the data. 最后,您将获得一个基于层次结构的数据视图。

You need a recursive algorithm. 您需要一个递归算法。 Try code below : 请尝试以下代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM