|
.NET TIPS
自作クラスによる配列をソート(並べ替え)するには?(LINQ版)[3.5、C#、VB]
デジタルアドバンテージ 遠藤 孝信
2009/05/28 |
|
|
「TIPS:自作クラスによる配列をソート(並べ替え)するには?」では、IComparableインターフェイス(System名前空間)を実装することにより、自作クラスの配列をソートする方法について解説したが、.NET Framework 3.5(Visual Studio 2008)以降では、LINQの機能を使って、もっと簡単に自作クラスの配列をソートできる。
OrderByメソッドによるソート
LINQでは、コレクションのソートはOrderByメソッドによって可能だ。このメソッドは配列(=System名前空間のArrayクラス)に対しても呼び出すことができる*。
* 配列に対するOrderByメソッドは、実際には拡張メソッドとして実装されており、その実体はEnumerableクラス(System.Linq名前空間)で実装されている。
|
以下のサンプル・プログラムでは、独自のWordクラスを定義し、そのオブジェクトの配列を、dataフィールドの値(文字列)の長さでソートしている。OrderByメソッドの引数には、ソート時の比較に使用されるキーを返すラムダ式を記述する。
// linqsort1.cs
using System;
using System.Linq;
public class Word {
public string data;
public Word(string s) { data = s; }
}
public class LinqSort1 {
static void Main() {
Word[] wordArray = {
new Word("むつき"),
new Word("きさらぎ"),
new Word("やよい"),
new Word("うづき"),
new Word("さつき"),
new Word("みなづき"),
new Word("ふみづき"),
new Word("はづき"),
new Word("ながつき"),
new Word("かんなづき"),
new Word("しもつき"),
new Word("しわす"),
};
// dataフィールドの文字列の長さでソート
wordArray = wordArray.OrderBy(n => n.data.Length)
.ToArray();
foreach (Word w in wordArray) {
Console.WriteLine(w.data);
}
// 出力:
// むつき
// やよい
// うづき
// さつき
// はづき
// しわす
// きさらぎ
// みなづき
// ふみづき
// ながつき
// しもつき
// かんなづき
}
}
// コンパイル方法:csc linqsort1.cs
|
' linqsort1.vb
Imports System
Imports System.Linq
Public Class Word
Public Dim data As String
Public Sub New(ByVal s As String)
data = s
End Sub
End Class
Public Class LinqSort1
Shared Sub Main()
Dim wordArray As Word() = { _
New Word("むつき"), _
New Word("きさらぎ"), _
New Word("やよい"), _
New Word("うづき"), _
New Word("さつき"), _
New Word("みなづき"), _
New Word("ふみづき"), _
New Word("はづき"), _
New Word("ながつき"), _
New Word("かんなづき"), _
New Word("しもつき"), _
New Word("しわす") _
}
' dataフィールドの文字列の長さでソート
wordArray = wordArray.OrderBy(Function(n) n.data.Length) _
.ToArray()
For Each w As Word In wordArray
Console.WriteLine(w.data)
Next
' 出力:
' むつき
' やよい
' うづき
' さつき
' はづき
' しわす
' きさらぎ
' みなづき
' ふみづき
' ながつき
' しもつき
' かんなづき
End Sub
End Class
' コンパイル方法:vbc linqsort1.vb
|
|
OrderByメソッドによるWord配列のソート(上:C#、下:VB) |
なお、OrderByメソッドの戻り値は、このプログラムの場合にはIEnumerable<Word>型(VBではIEnumerable(Of Word)型)となるが、ArrayToメソッドにより配列に変換できる。
ちなみに、OrderByメソッドによるソートは「安定した並べ替え」と呼ばれるもので、2つの要素のソート・キー(ここでは文字列の長さ)が等しい場合、ソート結果は元の順序が保持される。
複数の条件でソート
OrderByメソッドでのソート結果に対して、さらにソート条件を追加したい場合には、OrderByメソッドに続けてThenByメソッドを呼び出せばよい。
以下のサンプル・プログラムでは、Wordオブジェクトのdataフィールドの長さでソートし、さらにThenByメソッドにより“アイウエオ順”でソートしている。これにより、dataフィールドの長さが同じ要素は、それらの要素間でさらにアイウエオ順でソートされる。
// linqsort2.cs
using System;
using System.Linq;
public class Word {
public string data;
public Word(string s) { data = s; }
}
public class LinqSort2 {
static void Main() {
Word[] wordArray = {
new Word("むつき"),
new Word("きさらぎ"),
new Word("やよい"),
new Word("うづき"),
new Word("さつき"),
new Word("みなづき"),
new Word("ふみづき"),
new Word("はづき"),
new Word("ながつき"),
new Word("かんなづき"),
new Word("しもつき"),
new Word("しわす"),
};
// dataフィールドの文字列の長さでソートし、
// さらに、アイウエオ順でソート
wordArray = wordArray.OrderBy(n => n.data.Length)
.ThenBy(n => n.data)
.ToArray();
foreach (Word w in wordArray) {
Console.WriteLine(w.data);
}
// 出力:
// うづき
// さつき
// しわす
// はづき
// むつき
// やよい
// きさらぎ
// しもつき
// ながつき
// ふみづき
// みなづき
// かんなづき
}
}
// コンパイル方法:csc linqsort2.cs
|
' linqsort2.vb
Imports System
Imports System.Linq
Public Class Word
Public Dim data As String
Public Sub New(ByVal s As String)
data = s
End Sub
End Class
Public Class LinqSort2
Shared Sub Main()
Dim wordArray As Word() = { _
New Word("むつき"), _
New Word("きさらぎ"), _
New Word("やよい"), _
New Word("うづき"), _
New Word("さつき"), _
New Word("みなづき"), _
New Word("ふみづき"), _
New Word("はづき"), _
New Word("ながつき"), _
New Word("かんなづき"), _
New Word("しもつき"), _
New Word("しわす") _
}
' dataフィールドの文字列の長さでソートし、
' さらに、アイウエオ順でソート
wordArray = wordArray.OrderBy(Function(n) n.data.Length) _
.ThenBy(Function(n) n.data) _
.ToArray()
For Each w As Word In wordArray
Console.WriteLine(w.data)
Next
' 出力:
' うづき
' さつき
' しわす
' はづき
' むつき
' やよい
' きさらぎ
' しもつき
' ながつき
' ふみづき
' みなづき
' かんなづき
End Sub
End Class
' コンパイル方法:vbc linqsort2.vb
|
|
文字列の長さ+アイウエオ順でソート(上:C#、下:VB) |
なお、逆順にソートしたい場合には、OrderByメソッド/ThenByメソッドの代わりに、OrderByDescendingメソッド/ThenByDescendingメソッドを使用する。
利用可能バージョン:.NET Framework 3.5以降
カテゴリ:クラス・ライブラリ 処理対象:配列
カテゴリ:クラス・ライブラリ 処理対象:LINQ
使用ライブラリ:Arrayクラス(System名前空間)
使用ライブラリ:Enumerableクラス(System.Linq名前空間)
関連TIPS:自作クラスによる配列をソート(並べ替え)するには? |
|
generated by
|
|
Insider.NET 記事ランキング
本日
月間