在C#中对数组按字母顺序排序

23
希望有人能够帮忙。我创建了一个可变长度的数组,可以接受多个名称输入。我现在想按字母顺序对数组进行排序,并将其返回到控制台屏幕上。我认为Array.Sort(names)会为我完成这个操作,但是我遇到了异常。我已经查看了笔记、示例和在线资源,但似乎没有与我做的事情相匹配的内容。到目前为止,我的代码如下。我快要疯了!顺便说一下,我已经试图解决了这个问题,但是我无法做到,所以我需要有人解释我哪里错了,因为我是30多岁自学编程的人,今天是星期天,我正在努力工作,手头没有笔记来准确地覆盖这个问题。
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Student_Array
    {
        class Program
        {
            struct Student
            {
                public string Name;
            }
    
            static void Main(string[] args)
            {
                int numberOfStudents;
                Student[] names;
                string input;
    
                Console.WriteLine("How many students are there?");
                input = Console.ReadLine();
                numberOfStudents = int.Parse(input);
    
                names = new Student[numberOfStudents];
                
    
                for (int i = 0; i < names.Length; i++)
                {
                    Student s;
                    Console.WriteLine("Please enter student {0}'s name", (i + 1));
                    s.Name = Console.ReadLine();
                    names[i] = s;
                }
                ***Array.Sort<Student>(names);***
                for (int i = 0; i < names.Length; i++)
                {
                   
                    Console.WriteLine(names[i].Name);
                }
            }
        }
    }
7个回答

44

这就可以解决问题了。

Array.Sort(names, (x,y) => String.Compare(x.Name, y.Name));

抱歉,我标记了答案但没有回复谢谢。那很完美。 - user001

7
你的问题可能是混淆了学生和姓名的概念。通过定义Student结构体,你正在创建一个可以表示不仅仅是姓名的实体。例如,你可以扩展它以包括年龄家乡等信息。(因此,将数组命名为students而不是names可能更有意义。)
struct Student
{
    public string Name;
    public int Age;
    public string Hometown;
}

考虑到可能有多个字段,Array.Sort 方法需要知道你想按什么排序列表。你是想按姓名、年龄还是家乡排序学生?
根据 MSDN 文档 Array.Sort<T>
对整个数组中的元素使用每个元素的 IComparable<T> 通用接口实现进行排序。
这意味着你要排序的类型 - 在你的情况下是 Student - 必须实现 IComparable<T> 接口,以便 Array.Sort 实现知道它应该如何比较两个 Student 实例。如果你确信学生总是按姓名排序,可以这样实现:
struct Student : IComparable<Student>
{
    public string Name;
    public int Age;
    public string Hometown;

    public int CompareTo(Student other)
    {
        return String.Compare(this.Name, other.Name);
    }
}

或者,您可以提供一个函数来从排序方法本身中提取排序键。实现这一点的最简单方法是通过LINQ的OrderBy方法:

names = names.OrderBy(s => s.Name).ToArray();

正确,他如何对其进行排序?这不是一个答案。 - It'sNotALie.
4
@newStackExchangeInstance:当然是一个答案。如果他实现了IComparable接口,只需调用Array.Sort方法即可解决他的问题。 - Fabian Bigler

5

如果您扩展学生类以实现IComparable,则可以直接使用Sort

    struct Student : IComparable<Student>
    {
        public string Name;
        public int CompareTo(Student other)
        {
            return String.Compare(Name, other.Name,
                   StringComparison.CurrentCultureIgnoreCase);
        }
    }

您可以将比较 lambda 函数传递给 Sort 方法...
Array.Sort<Student>(names, (x, y) => String.Compare(x.Name, y.Name,
                                     StringComparison.CurrentCultureIgnoreCase));

...或者作为第三个选项,只需创建一个新的、排序后的数组;

var newArray = names.OrderBy(x => x.Name.ToLower()).ToArray();

对于最后一个,也许可以建议按 x => x.Name.ToLower() 进行排序。 - Elle
@JordanTrudgett 啊,是的,我漏掉了最后一部分 :) - Joachim Isaksson

1
你也可以使用这个方法,而不是使用Array.Sort。
names = names.OrderBy(p => p.Name).ToArray();

1
创建一个比较器类。
class StudentComparer : IComparer<Student>
{
    public int Compare(Student a, Student b)
    {
        return a.Name.CompareTo(b.Name);
    }
}

排序:

Array.Sort(students,new StudentComparer());

0

如果你想按照你的Student数组中Student对象的name属性进行排序,你可以使用以下代码:

Array.Sort(names, (s1, s2) => String.Compare(s1.Name, s2.Name));

这将对你的数组进行原地排序,或者使用 System.Linq

names = names.OrderBy(s => s.Name).ToArray();

可以使用.ToArray().ToList()将排序后的IEnumerable返回为数组或列表。

请记得在需要时进行不区分大小写的排序,如另一个答案中所指出的那样,可以在String.Compare中这样做:

String.Compare(s1.Name, s2.Name, StringComparison.CurrentCultureIgnoreCase)

-4

你可以在这里找到基本算法之一:简单冒泡排序c#

你需要进行一些修改,因为这个例子是针对整数的,对于字符串,你必须比较名称。

你可以找到更好的排序算法。现在冒泡排序对你来说还可以。


3
对于没有给出答案,而是提到其他链接或对提问者来说不是具体答案的短语,我会给予-1的评价。请翻译上述内容。 - Martin Mulder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接