首先,製作一棵樹,然後遞歸地從根下降到葉子。有很多方法可以做到這一點,這裏是一個:
class Message {
public Message(int message_id, string text, int? parent_message_id) {
Debug.Assert(message_id < int.MaxValue);
MessageID = message_id;
ParentMessageID = parent_message_id;
Text = text;
}
public readonly int MessageID;
public readonly string Text;
public readonly int? ParentMessageID;
public static IEnumerable<Message> OrderByHierarchy(IEnumerable<Message> messages) {
// Key: ParentMessageID (null substituted with int.MaxValue).
// Value: All messages sharing this parent.
var dict = messages.GroupBy(m => m.ParentMessageID ?? int.MaxValue).ToDictionary(grouping => grouping.Key);
// For each root, recursively traverse its children.
return dict[int.MaxValue].SelectMany(root => RecursiveDescent(dict, root));
}
static IEnumerable<Message> RecursiveDescent(Dictionary<int, IGrouping<int, Message>> dict, Message parent) {
yield return parent;
IGrouping<int, Message> children;
if (dict.TryGetValue(parent.MessageID, out children))
foreach (var child in children)
foreach (var descendent in RecursiveDescent(dict, child))
yield return descendent;
}
public override string ToString() {
return string.Format("{0} | {1} | {2}", MessageID, Text, ParentMessageID == null ? "null" : Convert.ToString(ParentMessageID));
}
}
class Program {
static void Main(string[] args) {
var messages = new[] {
new Message(1, "Text 1", null),
new Message(2, "Reply to Text 1", 1),
new Message(3, "Reply to Text 1 #2", 1),
new Message(4, "Reply to reply to text 1", 2),
};
foreach (var m in Message.OrderByHierarchy(messages))
Console.WriteLine(m);
}
}
此打印:
1 | Text 1 | null
2 | Reply to Text 1 | 1
4 | Reply to reply to text 1 | 2
3 | Reply to Text 1 #2 | 1
?爲什麼4在3之前? – BrokenGlass 2012-02-19 16:44:20
排序是對郵件的回覆(看ParentMessageID) – John 2012-02-19 16:48:52
按回復計數排序?但這並不能告訴我爲什麼4會在3 – BrokenGlass 2012-02-19 16:49:48