Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用两个条件进行排序,字符串升序和整数升序_C#_List_Sorting - Fatal编程技术网

C# 使用两个条件进行排序,字符串升序和整数升序

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对象,如:

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);
    });