如何按多个 T.attributes 对 List<T> 进行排序?
Posted
技术标签:
【中文标题】如何按多个 T.attributes 对 List<T> 进行排序?【英文标题】:How can I sort a List<T> by multiple T.attributes? 【发布时间】:2011-06-20 00:44:27 【问题描述】:假设我有一个歌曲列表。
Song
public string Name = "";
public int PlayOrder = 0;
现在我想首先按 PlayOrder 从零开始对它们进行排序,然后按名称按字母顺序排列。
因此,一组排序结果的示例将是 (Name, PlayOrder):
/*
Pachelbel's Canon, 0
A Happy Song, 4
Beethoven's 5th, 4
Some Other Song, 7
*/
看看 PlayOrder = 4 是如何按字母顺序排列的?这就是我想要的。
现在我只按一个字段排序:
List<Song> final = new List<Song>();
...
final.Sort((x, y) => x.PlayOrder.CompareTo(y.PlayOrder));
return final;
如上所示,我怎样才能按名称排序?
【问题讨论】:
【参考方案1】:return final.OrderBy(s => s.PlayOrder).ThenBy(s => s.Name);
【讨论】:
请注意,这将返回一个新的IEnumerable<Song>
序列,而不是就地对原始列表进行排序。
如果我希望它返回一个列表,我可以在最后添加一个 .ToList() 吗?
在您声明 OrderBy 执行稳定排序的其他评论中,您描述了稳定排序的含义。你能用同样的例子解释一下不稳定的排序吗?
她是一个很好的解释***.com/questions/3615100/…
Ooooooh 使用 THENBY - 但是当然!伙计,我需要更频繁地进行 RTFM :)【参考方案2】:
如果您想继续使用排序方法,您需要让比较功能更智能:
final.Sort((x, y) =>
var ret = x.PlayOrder.CompareTo(y.PlayOrder);
if (ret == 0) ret = x.Name.CompareTo(y.Name);
return ret;
);
如果您想使用 LINQ,那么您可以使用 K Ivanov 发布的内容。
【讨论】:
注意:Sort()“执行不稳定排序”,而OrderBy“执行稳定排序;即如果两个元素的键相等,则保留元素的顺序” 这是如何工作的?花括号之间发生了什么,我如何才能返回一个var?它回归什么?花括号内的代码会运行一次还是多次? 花括号中的代码是 lambda 表达式的主体,与您在问题中使用的 lambda 表达式相同。问题是,要做到这一点,我需要超过 1 个语句,所以我必须在身体周围放置大括号。基本上那里的代码是比较代码,排序算法会多次调用它(按: nlogn 的顺序)。【参考方案3】:如果您只有一种首选的歌曲排序方式class
,您应该实现IComparable
和/或IComparable<Song>
:
List<Song> songs = GetSongs();
songs.Sort(); // Sorts the current list with the Comparable logic
如果您有多种存储列表的方式,IEqualityComparer<T>
是您想要实现的接口。然后您可以在List<T>Sort()
中提供该比较器作为参数。
【讨论】:
以上是关于如何按多个 T.attributes 对 List<T> 进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
对list中的多个map按某个属性的值排序,null值放到最后