|
注意:配列やコレクション内の要素を方法を指定して検索する方法は、「配列やコレクション内の要素を方法を指定して検索する」に移動しました。 配列やコレクション内の要素を並び替える配列の並び替えは、Array.Sortメソッドで行います。コレクションの並び替えは、Sortメソッドで行います。 以下の例では、フォームにボタンコントロール"Button1"があるものとして、これをクリックした時にArrayListの並び替えを行なっています。 [VB.NET] 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click 'ArrayListに文字列を追加する Dim al As New System.Collections.ArrayList() al.Add("b") al.Add("aaaaa") al.Add("cc") '普通に並び替える al.Sort() '並び替えた結果を表示する Console.WriteLine("普通に並び替え") Dim i As Integer For i = 0 To al.Count - 1 Console.WriteLine("{0}: {1}", i, al(i)) Next End Sub [C#] //Button1のClickイベントハンドラ private void Button1_Click(object sender, System.EventArgs e) { //ArrayListに文字列を追加する System.Collections.ArrayList al = new System.Collections.ArrayList(); al.Add("b"); al.Add("aaaaa"); al.Add("cc"); //普通に並び替える al.Sort(); //並び替えた結果を表示する Console.WriteLine("普通に並び替え"); for (int i = 0; i < al.Count; i++) { Console.WriteLine("{0}: {1}", i, al[i]); } } 上記の結果、以下のように出力されます。 普通に並び替え 0: aaaaa 1: b 2: cc 配列の並び替えは、以下のようになります。 [VB.NET] 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click '並び替えを行う配列を作成 Dim strs() As String = {"b", "aaaaa", "cc"} '普通に並び替える Array.Sort(strs) '並び替えた結果を表示する Console.WriteLine("普通に並び替え") Dim i As Integer For i = 0 To strs.Length - 1 Console.WriteLine("{0}: {1}", i, strs(i)) Next i End Sub [C#] //Button1のClickイベントハンドラ private void Button1_Click(object sender, System.EventArgs e) { //並び替えを行う配列を作成 string[] strs = new string[] { "b", "aaaaa", "cc" }; //普通に並び替える Array.Sort(strs); //並び替えた結果を表示する Console.WriteLine("普通に並び替え"); for (int i = 0; i < strs.Length; i++) { Console.WriteLine("{0}: {1}", i, strs[i]); } } なお、.NET Framework 2.0以降では、Array.Sortジェネリックメソッドを使って、 このように並べ替え方を指定せずに、既定の方法で並べ替えを行うには、要素のクラスにIComparableインターフェイスが実装されている必要があります。既定の並び替えでは、IComparableインターフェイスのCompareToメソッドを使って大小が比較され、並び替えが行われます。 このようにIComparableインターフェイスを実装して並び替えの方法を指定する方法は「自作クラスの配列やコレクションでSortやBinarySearchを行う」で紹介しています。ここでは、それ以外のやり方で並び替え方を変更する方法を紹介します。 配列やコレクション内の要素を方法を指定して並び替えるIComparerインターフェイスここでは、文字列の長さが短い順番に並び替えてみます。ここではまず、IComparerインターフェイスを実装したクラス"LengthComparer"を定義し、Compareメソッドで2つのオブジェクトの比較方法を指定します。 Compareメソッドでは、1番目のパラメータと2番目のパラメータで渡されるデータを比較し、1番目の方が2番目より小さいときはマイナスの数、大きいときはプラスの数、同じときは0を返すようにします。 [VB.NET] '並び替える方法を定義するクラス 'IComparerインターフェイスを実装する Public Class LengthComparer Implements System.Collections.IComparer 'xがyより小さいときはマイナスの数、大きいときはプラスの数、 '同じときは0を返す Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _ Implements System.Collections.IComparer.Compare 'Nothingが最も小さいとする If x Is Nothing And y Is Nothing Then Return 0 End If If x Is Nothing Then Return -1 End If If y Is Nothing Then Return 1 End If 'String型以外の比較はエラー If (Not TypeOf x Is String) OrElse (Not TypeOf y Is String) Then Throw New ArgumentException() End If '文字列の長さを比較する Return CStr(x).Length - CStr(y).Length 'または、次のような方法もある 'Return CStr(x).Length.CompareTo(CStr(y).Length) End Function End Class 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click 'ArrayListに文字列を追加する Dim al As New System.Collections.ArrayList() al.Add("b") al.Add("aaaaa") al.Add("cc") '文字列の長さで並び替える Dim comp As New LengthComparer() al.Sort(comp) '並び替えた結果を表示する Console.WriteLine("文字列長で並び替え") Dim i As Integer For i = 0 To al.Count - 1 Console.WriteLine("{0}: {1}", i, al(i)) Next i End Sub [C#] //並び替える方法を定義するクラス //IComparerインターフェイスを実装する public class LengthComparer : System.Collections.IComparer { //xがyより小さいときはマイナスの数、大きいときはプラスの数、 //同じときは0を返す public int Compare(object x, object y) { //nullが最も小さいとする if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; //String型以外の比較はエラー if (!(x is string) || !(y is string)) throw new ArgumentException(); //文字列の長さを比較する return ((string)x).Length - ((string)y).Length; //または、次のような方法もある //return ((string)x).Length.CompareTo(((string)y).Length); } } //Button1のClickイベントハンドラ private void Button1_Click(object sender, System.EventArgs e) { //ArrayListに文字列を追加する System.Collections.ArrayList al = new System.Collections.ArrayList(); al.Add("b"); al.Add("aaaaa"); al.Add("cc"); //文字列の長さで並び替える LengthComparer comp = new LengthComparer(); al.Sort(comp); //並び替えた結果を表示する Console.WriteLine("文字列長で並び替え"); for (int i = 0; i < al.Count; i++) { Console.WriteLine("{0}: {1}", i, al[i]); } } 今度は以下のように出力されます。 文字列長で並び替え 0: b 1: cc 2: aaaaa 上記はコレクションの例ですが、配列でも同様に、 IComparable(T)ジェネリックインターフェイス.NET Framework 2.0以降では、IComparableインターフェイスに加えて、IComparable(T)ジェネリックインターフェイスも実装した方が良いでしょう。そして並び替えは、ジェネリックコレクションのSortメソッドなどで行います。 先のLengthComparerクラスにIComparable(T)ジェネリックインターフェイスも実装したクラスは、以下のようになります。 [VB.NET] '並び替える方法を定義するクラス 'IComparable(T)ジェネリックインターフェイスを実装する Public Class LengthComparer Implements System.Collections.IComparer, _ System.Collections.Generic.IComparer(Of String) 'xがyより小さいときはマイナスの数、大きいときはプラスの数、 '同じときは0を返す Public Function Compare(ByVal x As String, ByVal y As String) As Integer _ Implements System.Collections.Generic.IComparer(Of String).Compare 'Nothingが最も小さいとする If x Is Nothing AndAlso y Is Nothing Then Return 0 End If If x Is Nothing Then Return -1 End If If y Is Nothing Then Return 1 End If '文字列の長さを比較する Return x.Length - y.Length End Function Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _ Implements System.Collections.IComparer.Compare 'Nothingが最も小さいとする If x Is Nothing AndAlso y Is Nothing Then Return 0 End If If x Is Nothing Then Return -1 End If If y Is Nothing Then Return 1 End If 'String型以外の比較はエラー If (Not TypeOf x Is String) OrElse (Not TypeOf y Is String) Then Throw New ArgumentException() End If Return Me.Compare(CStr(x), CStr(y)) End Function End Class [C#] //並び替える方法を定義するクラス //IComparable(T)ジェネリックインターフェイスを実装する public class LengthComparer : System.Collections.IComparer, System.Collections.Generic.IComparer<string> { //xがyより小さいときはマイナスの数、大きいときはプラスの数、 //同じときは0を返す public int Compare(string x, string y) { //nullが最も小さいとする if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; //文字列の長さを比較する return x.Length - y.Length; } public int Compare(object x, object y) { //nullが最も小さいとする if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; //String型以外の比較はエラー if (!(x is string) || !(y is string)) throw new ArgumentException(); return this.Compare((string)x, (string)y); } } SortedListクラスSortedListクラスはキーと値のペアのコレクションで、キーで並び替えられます。キーの並び替え方は、IComparerによって変えることもできます。 .NET Framework 2.0以降では、ジェネリックバージョンの「System.Collections.Generic.SortedList(TKey, TValue)」または「SortedDictionary(TKey, TValue)」を使った方が良いでしょう。 以下の例では、SortedListクラスのキーに文字列の長さを指定することで、文字列の長さで並び替えられるようにしています。 [VB.NET] Dim strs() As String = {"b", "aaaaa", "cc"} 'SortedListを作成 Dim sl As New System.Collections.SortedList() '文字列の長さをキーとしてコレクションに追加する Dim s As String For Each s In strs sl.Add(s.Length, s) Next s '並び替えた結果を表示する Console.WriteLine("SortedListで並び替え") Dim i As Integer For i = 0 To sl.Count - 1 Console.WriteLine("{0}: {1}", i, sl.GetByIndex(i)) Next i [C#] string[] strs = new string[] { "b", "aaaaa", "cc" }; //SortedListを作成 System.Collections.SortedList sl = new System.Collections.SortedList(); //文字列の長さをキーとしてコレクションに追加する foreach (string s in strs) { sl.Add(s.Length, s); } //並び替えた結果を表示する Console.WriteLine("SortedListで並び替え"); for (int i = 0; i < sl.Count; i++) { Console.WriteLine("{0}: {1}", i, sl.GetByIndex(i)); } Array.Sort(Array, Array)メソッドArray.Sort(Array, Array)メソッドで配列を並び替える方法を紹介します。このメソッドでは、一方の配列に基づいて、もう一方の配列を並び替えます。この方法でも、IComparerによって並び替え方を変更することができます .NET Framework 2.0以降では、ジェネリックメソッド「Sort(TKey, TValue)(TKey[], TValue[])」を使った方が良いでしょう。 以下にArray.Sort(Array, Array)メソッドを使って並び替えを行う例を示します。 [VB.NET] '並び替えを行う配列 Dim strs() As String = {"b", "aaaaa", "cc"} '並び替えの対象となる配列を作成 Dim keys(strs.Length - 1) As Integer Dim i As Integer For i = 0 To keys.Length - 1 '文字列の長さを格納する keys(i) = strs(i).Length Next i '並び替えを行う Array.Sort(keys, strs) '並び替えた結果を表示する Console.WriteLine("Array.Sort(Array, Array)で並び替え") For i = 0 To strs.Length - 1 Console.WriteLine("{0}: {1}", i, strs(i)) Next i [C#] //並び替えを行う配列 string[] strs = new string[] { "b", "aaaaa", "cc" }; //並び替えの対象となる配列を作成 int[] keys = new int[strs.Length]; for (int i = 0; i < keys.Length; i++) { //文字列の長さを格納する keys[i] = strs[i].Length; } //並び替えを行う Array.Sort(keys, strs); //並び替えた結果を表示する Console.WriteLine("Array.Sort(Array, Array)で並び替え"); for (int i = 0; i < strs.Length; i++) { Console.WriteLine("{0}: {1}", i, strs[i]); } Comparison(T)ジェネリックデリゲート.NET Framework 2.0からは、Comparison(T)ジェネリックデリゲートを使って並び替え方を変更することもできます。ただし、ジェネリックではないコレクションではこの方法は使えません。 以下にこの方法による例を示します。CompareByLengthメソッドで並び替え方を指定しています。 [VB.NET] 'xがyより小さいときはマイナスの数、大きいときはプラスの数、 '同じときは0を返す Public Function CompareByLength(ByVal x As String, ByVal y As String) _ As Integer 'Nothingが最も小さいとする If x Is Nothing AndAlso y Is Nothing Then Return 0 End If If x Is Nothing Then Return -1 End If If y Is Nothing Then Return 1 End If '文字列の長さを比較する Return x.Length - y.Length End Function 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click 'List(Of string)に文字列を追加する Dim sl As New List(Of String) sl.Add("b") sl.Add("aaaaa") sl.Add("cc") '並び替えを行う sl.Sort(AddressOf CompareByLength) '並び替えた結果を表示する Console.WriteLine("Comparison(T)で並び替え") Dim i As Integer For i = 0 To sl.Count - 1 Console.WriteLine("{0}: {1}", i, sl(i)) Next i End Sub [C#] //xがyより小さいときはマイナスの数、大きいときはプラスの数、 //同じときは0を返す public int CompareByLength(string x, string y) { //nullが最も小さいとする if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; //文字列の長さを比較する return x.Length - y.Length; } //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { //List<string>に文字列を追加する List<string> sl = new List<string>(); sl.Add("b"); sl.Add("aaaaa"); sl.Add("cc"); //並び替えを行う sl.Sort(CompareByLength); //並び替えた結果を表示する Console.WriteLine("Comparison(T)で並び替え"); for (int i = 0; i < sl.Count; i++) { Console.WriteLine("{0}: {1}", i, sl[i]); } } LINQ.NET Framework 3.5からは、LINQ(統合言語クエリ、Language-Integrated Query)によって並び替えることもできます。なおLINQを使用するには、参照設定に「System.Core.dll」が追加されている必要があります。 LINQにより文字列の配列を文字列長順に並び替える例を示します。 [VB.NET] 'Imports System.Linq 'がソースファイルの一番上に書かれているものとする '並び替えを行う配列 Dim strs As String() = New String() {"b", "aaaaa", "cc"} 'クエリの作成 Dim query As IEnumerable(Of String) = From str In strs _ Order By str.Length _ Select str 'または、 'Dim query = From str In strs _ ' Order By str.Length _ ' Select str 'クエリを実行し、配列を作成 Dim sortedStrs As String() = query.ToArray() '並び替えた結果を表示する Console.WriteLine("LINQで並び替え") For i As Integer = 0 To sortedStrs.Length - 1 Console.WriteLine("{0}: {1}", i, sortedStrs(i)) Next [C#] //using System.Linq; //がソースファイルの一番上に書かれているものとする //並び替えを行う配列 string[] strs = new string[] { "b", "aaaaa", "cc" }; //クエリの作成 IEnumerable<string> query = from str in strs orderby str.Length select str; //または、 //var query = from str in strs // orderby str.Length // select str; //クエリを実行し、配列を作成 string[] sortedStrs = query.ToArray(); //並び替えた結果を表示する Console.WriteLine("LINQで並び替え"); for (int i = 0; i < sortedStrs.Length; i++) { Console.WriteLine("{0}: {1}", i, sortedStrs[i]); } LINQによる並べ替えの詳細は、MSDNの「Language-Integrated Query (LINQ) データの並べ替え」をご覧ください。 どの方法が一番早いかArray.Sortメソッド、List(T).Sortメソッド、LINQの3つの並び替え方法について、ベンチマークの結果が「Sort String Array」で紹介されています。これによると、List(T).Sortメソッドが若干速く、要素数が多いときはLINQが遅いようですが、3つの方法の速さの違いはそれほどないようです。 文字列の並び替え文字列の配列やコレクションを並び替える方法については、こちらでさらに補足しています。そちらでは、大文字、小文字を区別しない並び替えや、カルチャに依存しない並び替えなどについて説明しています。
|
|
Copyright 2002-2008 DOBON!. All rights reserved.
|