C# 使用两个条件进行排序,字符串升序和整数升序
如何根据两个不同的标准执行排序 例如,我有person对象,如:C# 使用两个条件进行排序,字符串升序和整数升序,c#,list,sorting,C#,List,Sorting,如何根据两个不同的标准执行排序 例如,我有person对象,如: Person具有属性FirstName(字符串)、LastName和Rank(int) 示例数据如下: Xavier Smith 1 Alexander Smith 2 Alexander Smith 1 Bob Hawke 2 它应该按名字的字母顺序排序,然后按等级排序,例如结果: Alexander Smith 1 Alexander Smith 2 Bob Hawke 2 Xavier
Person
具有属性FirstName
(字符串)、LastName
和Rank
(int)
示例数据如下:
Xavier Smith 1
Alexander Smith 2
Alexander Smith 1
Bob Hawke 2
它应该按名字的字母顺序排序,然后按等级排序,例如结果:
Alexander Smith 1
Alexander Smith 2
Bob Hawke 2
Xavier Smith 1
到目前为止,我已经尝试了以下方法,但无法正常工作:
peopleList
是List
将给出正确排序的完全相同的列表,对吗?LINQ方法 使用LINQ,您可以使用和: 这将返回一个
IEnumerable
。如果您确实需要列表
请在末尾添加.ToList()
如果要使用Sort
方法,则需要编写自定义比较器
编辑:使用ToList()
返回一个新列表。如果要对现有列表进行排序,则应使用sort
方法,该方法不返回列表,而是对当前列表进行操作(这是一种void
方法)
排序/比较方法
使用:list.Sort(newpersoncomparer())代码>
这是比较器代码。这本书是根据《圣经》改编的,所以我建议阅读他们的评论,以了解为什么它是这样结构的
public class PersonComparer : IComparer<Person>
{
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);
}
}
}
}
}
公共类个人比较者:IComparer
{
公共整数比较(人员x、人员y)
{
如果(x==null)
{
如果(y==null)
{
返回0;
}
其他的
{
返回-1;
}
}
其他的
{
如果(y==null)
{
返回1;
}
其他的
{
int retval=x.FirstName.CompareTo(y.FirstName);
如果(返回值!=0)
{
返回返回;
}
其他的
{
返回x.Rank.CompareTo(y.Rank);
}
}
}
}
}
我喜欢LINQ的答案。如果这不是一个选项,您可以随时使用
(x,y) => 2*string.Compare(x.Name,y.Name) + x.Rank.CompareTo(y.Rank)
因此,字符串比较总是占主导地位,除非它等于0,否则实际上您非常熟悉就地排序lambda语法。您只是忽略了一个事实,即lambda可以包含在它们自己的范围内:
peopleList.Sort(new Comparison<Person>((x,y) =>
{
int result = x.FirstName.CompareTo(y.FirstName);
return (result != 0) ? result : x.Rank.CompareTo(y.Rank);
}));
peopleList.Sort(新比较((x,y)=>
{
int result=x.FirstName.CompareTo(y.FirstName);
返回(结果!=0)?结果:x.Rank.CompareTo(y.Rank);
}));
这比编写自己的IComparer
要省力一点 其他答案似乎比这更优雅,它们让我觉得自己更像一个傻瓜,但是如果你知道如何像这样排序,你可以以任何方式对任何类型的列表进行排序,而不需要知道太多。而且不需要编写一个全新的类(尽管如果您在代码的其他部分对其他类似列表进行排序,那么编写一个比较器类可能会很有用)
我真的必须读更多关于LINQ的书,它似乎让我的生活变得更加轻松@baron查看我的编辑,我在您最近的编辑中对您的问题进行了评论。@baron我添加了一个比较器,可与Sort()
一起使用。感谢您的详细回答Ahmad@baron不客气:)这里还有其他一些好答案。CompareTo的思想是查看项目是否相等、大于或小于,然后根据整数返回值进行排序。通过在返回语句或lambda中使用一些三元运算符,比较器的大小当然可以减小,如其他人所示。如果您打算在许多地方使用这种类型的比较,那么创建一个类会有所帮助,否则,在没有新类的情况下,可以就地进行罕见的比较。@a虽然很好,但您需要翻转比较。首先比较FirstName,然后在三元比较秩的第二部分。
public class PersonComparer : IComparer<Person>
{
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);
}
}
}
}
}
(x,y) => 2*string.Compare(x.Name,y.Name) + x.Rank.CompareTo(y.Rank)
peopleList.Sort(new Comparison<Person>((x,y) =>
{
int result = x.FirstName.CompareTo(y.FirstName);
return (result != 0) ? result : 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);
});