web-dev-qa-db-ja.com

C#で配列をアルファベット順に並べ替える

誰かが助けてくれることを願っています。複数の名前入力を受け入れる可変長配列を作成しました。次に、配列をアルファベット順に並べ替えて、コンソール画面に返します。

Array.Sort(names);私のためにこれを行うでしょうが、例外がスローされています。私はメモ、例、オンラインを見てきましたが、私がしていることに一致するものはないようです。

これまでに以下を実行しました。私はここで髪を引きちぎります。 PS私は何時間もこれを理解しようとしました、そして私は自分自身を学ぶために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);
            }
        }
    }
}
17
user001

これはトリックをしなければならない

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

ここでの問題は、学生と名前の概念を混乱させていることかもしれません。 Student構造体を定義することにより、単なる名前以上のものを表すことができるエンティティを作成しています。たとえば、AgeHometownなどを含めるように拡張できます。 (このため、配列にstudentsではなくnamesと名前を付ける方が意味がある場合があります。)

struct Student
{
    public string Name;
    public int Age;
    public string Hometown;
}

複数のフィールドの可能性を考えると、Array.Sortメソッドは、リストを何にソートするかを知る必要があります。名前順、年齢順、または出身地順で生徒を注文しますか?

Array.Sort<T> に関するMSDNドキュメントに従って:

配列の各要素のIComparable<T>ジェネリックインターフェイス実装を使用して、Array全体の要素を並べ替えます。

これは、ソートしようとしている型(この場合はStudent)がIComparable<T>の実装で Array.Sort インターフェースを実装する必要があることを意味します。 2つの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);
    }
}

または、sortメソッド自体にソートキーを抽出する関数を提供することもできます。これを実現する最も簡単な方法は、LINQ OrderByメソッドを使用することです。

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

次の場合は、Sortをそのまま使用することもできますStudentを拡張してIComparableを実装する;

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

...または、比較ラムダをソートに渡すことができます...

Array.Sort<Student>(names, (x, y) => String.Compare(x.Name, y.Name,
                                     StringComparison.CurrentCultureIgnoreCase));

...または3番目のオプションとして、新しいソート済み配列を作成します。

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

比較クラスを作成する

class StudentComparer : IComparer<Student>
{
    public int Compare(Student a, Student b)
    {
        return a.Name.CompareTo(b.Name);
    }
}

ソート:

Array.Sort(students,new StudentComparer());
1
Raz Megrelidze

name配列内のStudentオブジェクトのStudentプロパティでソートするには、次のように使用できます

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

配列をその場で並べ替えるか、_System.Linq_を使用します。

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

並べ替えられたIEnumerableを配列(.ToArray())またはリスト(.ToList()。)として返すことができます。

別の回答で指摘されているように、重要な場合は大文字と小文字を区別せずに並べ替えることを忘れないでください。これは次のように_String.Compare_で行うことができます。

_String.Compare(s1.Name, s2.Name, StringComparison.CurrentCultureIgnoreCase)
_
0
Elle

Array.Sortを使用する代わりに、これも使用できます。

names = names.OrderBy(p => p.Name).ToArray();
0
cvraman