2017-02-26 11 views
0

ネストされた返信でコメントを並べ替えるにはどうすればよいですか? 私のデータは次のようになります。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 
* */ 

私はこれをどのように行うことができますか?

+0

どのように深さを計算しますか?そしてあなたの出力の前には何がありますか? – bc004346

答えて

1

これを行うには、階層ソートアルゴリズムを作成する必要があります。今実際の質問は、それを印刷したり、そのようにソートされた別のコレクションに含まれたりしたいのですか?

最初に、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; } 
} 

現在、私はあなたと同じコードを使用して、現在のコメントの子供を理解する簡単な列挙体システムを作成しました。これは、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

再帰アルゴリズムが必要です。以下のコードを試してください:

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

子供、孫、そして...を印刷する方法を尋ねることがあります。 – Paparazzi

+0

このコードはすべての子孫を表示します。 – jdweng

+0

私のためにすべてを印刷しない – Paparazzi

関連する問題