如何使用lambda或linq排列列表

本文关键字:排列 列表 linq 何使用 lambda | 更新日期: 2023-09-27 18:25:13

如何使用lambda或linq排列列表以下是列表(Tickets),该列表有一个名为MessageId的字段,每个MessageId可能包含也可能不包含子消息,依此类推(即ReplyMessageId)

我有以下列表

   MessageId        ReplyMessageId       Message                    PostedDate
  66                  65             "Hello"                    6/25/2013 10:00:01 AM
  68                  66             "[Reply to Hello]-1"       6/25/2013 10:12:23 AM
  72                  66             "[Reply to Hello]-2"       6/25/2013 11:12:23 AM
  73                  66             "[Reply to Hello]-3"       6/26/2013 9:12:23 AM
  74                  66             "[Reply to Hello]-4"       6/25/2013 11:12:12 PM
  75                  68             "[Reply to Hello-1] -1"    6/25/2013 11:05:12 AM
  76                  73             "[Reply to Hello-3] -1"    6/26/2013 10:10:23 AM
  80                  75             "[Reply to Hello-1-1] -1"  6/25/2013 11:45:22 AM
  81                  68             "[Reply to Hello-1]-1"     6/25/2013 11:45:22 AM

例如,MessageId 68是具有子消息75、81的MessageId 66和MessageId 68的回复。

输出列表应采用以下格式。

  MessageId        ReplyMessageId       Message                    PostedDate
  66                  65             "Hello"                    6/25/2013 10:00:01 AM
  74                  66             "[Reply to Hello]-4"       6/25/2013 11:12:12 PM
  73                  66             "[Reply to Hello]-3"       6/26/2013 9:12:23 AM
  76                  73             "[Reply to Hello-3]-1"     6/26/2013 10:10:23 AM
  72                  66             "[Reply to Hello]-2"       6/25/2013 11:12:23 AM
  68                  66             "[Reply to Hello]-1"       6/25/2013 10:12:23 AM
  81                  68             "[Reply to Hello-1]-1"     6/25/2013 11:45:22 AM
  75                  68             "[Reply to Hello-1]-1"     6/25/2013 11:05:12 AM
  80                  75             "[Reply to Hello-1-1]-1"   6/25/2013 11:45:22 AM     

如何使用lambda或linq排列列表

我只需要构建树;比试图在平坦时处理它简单得多:

class MessageItem
{
    private readonly List<MessageItem> children = new List<MessageItem>();
    public List<MessageItem> Children { get { return children; } }
    public int MessageId { get; set; }
    public int ReplyMessageId { get; set; }
    public DateTime PostedDate { get; set; }
    public string Message { get; set; }
    public override string ToString()
    {
        return string.Format("{0} ({1}): {2}", MessageId, ReplyMessageId, Message);
    }
}
static void Main()
{
    // input data
    var cu = CultureInfo.InvariantCulture;
    var data = new[] {
        new MessageItem{ MessageId = 66, ReplyMessageId = 65, Message = "Hello", PostedDate = DateTime.Parse("6/25/2013 10:00:01 AM", cu)},
        new MessageItem{ MessageId = 68, ReplyMessageId = 66, Message = "[Reply to Hello]-1", PostedDate = DateTime.Parse("6/25/2013 10:12:23 AM",cu)},
        new MessageItem{ MessageId = 72, ReplyMessageId = 66, Message = "[Reply to Hello]-2", PostedDate = DateTime.Parse("6/25/2013 11:12:23 AM",cu)},
        new MessageItem{ MessageId = 73, ReplyMessageId = 66, Message = "[Reply to Hello]-3", PostedDate = DateTime.Parse("6/26/2013 9:12:23 AM",cu)},
        new MessageItem{ MessageId = 74, ReplyMessageId = 66, Message = "[Reply to Hello]-4", PostedDate = DateTime.Parse("6/25/2013 11:12:12 PM",cu)},
        new MessageItem{ MessageId = 75, ReplyMessageId = 68, Message = "[Reply to Hello-1] -1", PostedDate = DateTime.Parse("6/25/2013 11:05:12 AM",cu)},
        new MessageItem{ MessageId = 76, ReplyMessageId = 73, Message = "[Reply to Hello-3] -1", PostedDate = DateTime.Parse("6/26/2013 10:10:23 AM",cu)},
        new MessageItem{ MessageId = 80, ReplyMessageId = 75, Message = "[Reply to Hello-1-1] -1", PostedDate = DateTime.Parse("6/25/2013 11:45:22 AM",cu)},
        new MessageItem{ MessageId = 81, ReplyMessageId = 68, Message = "[Reply to Hello-1]-1", PostedDate = DateTime.Parse("6/25/2013 11:45:22 AM",cu)},
    };
    // build the hierarchy, using a parent lookup
    var ids = data.ToDictionary(x => x.MessageId);
    List<MessageItem> orphans = new List<MessageItem>();
    foreach (var item in data)
    {
        MessageItem parent;
        (ids.TryGetValue(item.ReplyMessageId, out parent) ? parent.Children : orphans).Add(item);
    }
    // write the hierarchy using a stack (to avoid recursion)
    Stack<MessageItem> pending = new Stack<MessageItem>();
    // the following looks backwards, but isn't (the stack reverses the order)
    // personally, I would use => x.PostedDate, but that gives a different order
    // (the *correct* order, IMO); this gives the *requested* order; no point
    // ordering *after* MessageId, as presumably that is unique
    foreach (var msg in orphans.OrderBy(x => x.MessageId)) pending.Push(msg); 
    while (pending.Count > 0)
    {
        var next = pending.Pop();
        Console.WriteLine(next);
        foreach (var msg in next.Children.OrderBy(x => x.MessageId)) pending.Push(msg);
    }
}