按两个条件排序,字符串升序,int升序

如何根据两个不同的标准进行排序?

例如,我有人物对象,如:

具有FirstName (字符串), LastNameRank (int)属性的Person

像这样的示例数据:

 Xavier Smith 1 Alexander Smith 2 Alexander Smith 1 Bob Hawke 2 

它应按字母顺序排序FirstName,然后按排名排序,例如:

 Alexander Smith 1 Alexander Smith 2 Bob Hawke 2 Xavier Smith 1 

到目前为止,我已经尝试了以下内容,但它无法正常工作:

peopleListList

 peopleList.Sort(new Comparison((x,y) => x.Rank.CompareTo(y.Rank))); peopleList.Sort(new Comparison((x, y) => string.Compare(x.Name, y.Name))); 

谢谢

编辑:为了避免更改我的代码太多,我真的想保留列表,如果我将上面的行更改为:

 peopleList.OrderBy(person => person.FirstName).ThenBy(person => person.Rank).ToList(); 

会给出完全相同的列表,只是正确排序,对吗?

LINQ方法

使用LINQ,您可以使用OrderBy和ThenBy :

 var result = peopleList.OrderBy(p => p.FirstName).ThenBy(p => p.Rank); 

这将返回IEnumerable 。 如果你真的需要List添加一个.ToList()

如果要使用Sort方法,则需要编写自定义比较器。

编辑:使用ToList()返回一个新列表。 如果要对现有列表进行排序,则应使用Sort方法,该方法不返回列表,而是对当前列表进行操作(它是一种void方法)。

排序/比较方法

使用: list.Sort(new PersonComparer());

这是比较器代码。 它是根据MSDN示例改编的,所以我建议阅读他们用来理解为什么这样结构的注释。

 public class PersonComparer : IComparer { public int Compare(Person x, Person y) { if (x == null) { if (y == null) { return 0; } else { return -1; } } else { if (y == null) { return 1; } else { int retval = x.FirstName.CompareTo(y.FirstName); if (retval != 0) { return retval; } else { return x.Rank.CompareTo(y.Rank); } } } } } 

其他答案似乎比这更优雅,它们让我感觉更像是一个菜鸟,但是如果你理解如何排序,你可以以任何方式排序任何类型的列表,而不需要知道任何东西。 并且不需要编写一个全新的类(尽管如果在代码的其他部分中对其他类似的列表进行排序,编写一个比较器类会很有用)。

 peopleList.Sort((x, y) => { int compare = x.FirstName.CompareTo(y.FirstName); if (compare != 0) return compare; compare = x.Rank.CompareTo(y.Rank); if (compare != 0) return compare; return x.LastName.CompareTo(y.LastName); }); 

你实际上非常接近就地排序lambda语法。 你只是错过了lambdas可以包含在自己的范围内的事实:

 peopleList.Sort(new Comparison((x,y) => { int result = x.FirstName.CompareTo(y.FirstName); return (result != 0) ? result : x.Rank.CompareTo(y.Rank); })); 

这比编写自己的IComparer要少一点!

我喜欢LINQ的答案。 如果这不是一个选项,你可以随时使用

 (x,y) => 2*string.Compare(x.Name,y.Name) + x.Rank.CompareTo(y.Rank) 

这样字符串比较总是占主导地位,除非它等于0