【C#】
シーケンスの要素をキーに従って昇順に並べ替えます。 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable【VB】source, Func keySelector) 指定された比較子を使用してシーケンスの要素を昇順に並べ替えます。 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>: (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
シーケンスの要素をキーに従って昇順に並べ替えます。 <ExtensionAttribute> Public Shared Function OrderBy(Of TSource, TKey) (source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey)) As IOrderedEnumerable(Of TSource) 指定された比較子を使用してシーケンスの要素を昇順に並べ替えます。 <ExtensionAttribute> Public Shared Function OrderBy(Of TSource, TKey) (source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey), comparer As IComparer(Of TKey)) As IOrderedEnumerable(Of TSource)
Enumerable.ThenBy メソッド
【C#】
キーに従って、シーケンス内の後続の要素を昇順で配置します。 ThenBy<TSource, TKey>(IOrderedEnumerable<TSource>, Func<TSource, TKey>) 指定された比較子を使用して、シーケンス内の後続の要素を昇順で配置します。 ThenBy<TSource, TKey>(IOrderedEnumerable<TSource>, Func<TSource, TKey>, IComparer<TKey>)【VB】
キーに従って、シーケンス内の後続の要素を昇順で配置します。 ThenBy(Of TSource, TKey)(IOrderedEnumerable(Of TSource), Func(Of TSource, TKey)) 指定された比較子を使用して、シーケンス内の後続の要素を昇順で配置します。 ThenBy(Of TSource, TKey)(IOrderedEnumerable(Of TSource), Func(Of TSource, TKey), IComparer(Of TKey))
簡単に言うと…
シーケンス(配列やコレクションなど)の各要素を昇順に並び替える。
データを並び替える項目が一つ目ならOrderByを使用しします。
二つ目からはThenByを使用します。
このメソッドは遅延実行されます。
テストデータです。
【C#】
private class Fruit { public string Name { get; set; } public string Rank { get; set; } public decimal Price { get; set; } } var fruits = new List<Fruit>() { new Fruit(){Name = "りんご", Rank = "A" , Price = 1000 }, new Fruit(){Name = "みかん", Rank = "A" , Price = 600 }, new Fruit(){Name = "ぶどう", Rank = "B" , Price = 1200 }, new Fruit(){Name = "りんご", Rank = "B" , Price = 800 }, new Fruit(){Name = "みかん", Rank = "A" , Price = 500 } };【VB】
Private Class Fruit Public Property Name As String Public Property Rank As String Public Property Price As Decimal End Class Dim fruits = New List(Of Fruit)() From { New Fruit() With {.Name = "りんご", .Rank = "A", .Price = 1000}, New Fruit() With {.Name = "みかん", .Rank = "A", .Price = 600}, New Fruit() With {.Name = "ぶどう", .Rank = "B", .Price = 1200}, New Fruit() With {.Name = "りんご", .Rank = "B", .Price = 800}, New Fruit() With {.Name = "みかん", .Rank = "A", .Price = 500} }
果物リストを名前で昇順に並び替えます。
【C#】
//名称を昇順で並び替え var ordered = fruits.OrderBy(itm => itm.Name); //出力 foreach (var itm in ordered) Console.WriteLine("名称={0}, ランク={1}, 値段={2}", itm.Name, itm.Rank, itm.Price.ToString("#,##0")); //名称=ぶどう, ランク=B, 値段=1,200 //名称=みかん, ランク=A, 値段=600 //名称=みかん, ランク=A, 値段=500 //名称=りんご, ランク=A, 値段=1,000 //名称=りんご, ランク=B, 値段=800【VB】
'名称を昇順で並び替え Dim ordered = fruits.OrderBy(Function(itm) itm.Name) '出力 For Each itm In ordered Console.WriteLine("名称={0}, ランク={1}, 値段={2}", itm.Name, itm.Rank, itm.Price.ToString("#,##0")) Next '名称=ぶどう, ランク=B, 値段=1,200 '名称=みかん, ランク=A, 値段=600 '名称=みかん, ランク=A, 値段=500 '名称=りんご, ランク=A, 値段=1,000 '名称=りんご, ランク=B, 値段=800
果物リストを名前の昇順、値段の昇順に並び替えます。
一つ目のソート条件である名前はOrderByメソッドで指定し、二つ目のソート条件である値段はThenByメソッドで指定します。
【C#】
//名称の昇順、値段の昇順で並び替え var ordered = fruits.OrderBy(itm => itm.Name).ThenBy(itm => itm.Price); //出力 foreach (var itm in ordered) Console.WriteLine("名称={0}, ランク={1}, 値段={2}", itm.Name, itm.Rank, itm.Price.ToString("#,##0")); //名称=ぶどう, ランク=B, 値段=1,200 //名称=みかん, ランク=A, 値段=500 //名称=みかん, ランク=A, 値段=600 //名称=りんご, ランク=B, 値段=800 //名称=りんご, ランク=A, 値段=1,000【VB】
'名称の昇順、値段の昇順で並び替え Dim ordered = fruits.OrderBy(Function(itm) itm.Name).ThenBy(Function(itm) itm.Price) '出力 For Each itm In ordered Console.WriteLine("名称={0}, ランク={1}, 値段={2}", itm.Name, itm.Rank, itm.Price.ToString("#,##0")) Next '名称=ぶどう, ランク=B, 値段=1,200 '名称=みかん, ランク=A, 値段=500 '名称=みかん, ランク=A, 値段=600 '名称=りんご, ランク=B, 値段=800 '名称=りんご, ランク=A, 値段=1,000
今まで使う必要に迫られたことはないのですが…
OrderByメソッドやThenByメソッドの第二引数にICompareを指定することで、独自の並び替え方法でソートすることができます。
例えば「2015/1/1, 2015/11/11, 2015/5/31, 2015/4, 20」といった日付を表す文字列があったとします。
これらを文字列としてソートすると「20, 2015/1/1, 2015/11/11, 2015/4, 2015/5/31」となります。
日付と考えるのであれば「20, 2015/1/1, 2015/4, 2015/5/31, 2015/11/11」と並んで欲しいです。
このようなとき独自のソート方法を定義します。
独自のソート方法を定義するには
IComparerインターフェイスを実装したクラスを作成し、Compareメソッドに比較方法を記述します。
【C#】
private class CompareDateString : System.Collections.Generic.IComparer<string> { public int Compare(string x, string y) { //xがyより小さいときはマイナスの数、大きいときはプラスの数、同じときは0を返すようにする string[] aryX = x.Split('/'); string[] aryY = y.Split('/'); string xDateString; xDateString = aryX[0].PadLeft(4, '0'); xDateString += (aryX.Length > 1 ? aryX[1].PadLeft(2, '0') : "00"); xDateString += (aryX.Length > 2 ? aryX[2].PadLeft(2, '0') : "00"); string yDateString; yDateString = aryY[0].PadLeft(4, '0'); yDateString += (aryY.Length > 1 ? aryY[1].PadLeft(2, '0') : "00"); yDateString += (aryY.Length > 2 ? aryY[2].PadLeft(2, '0') : "00"); int i = xDateString.CompareTo(yDateString); return i; } }【VB】
Private Class CompareDateString : Implements System.Collections.Generic.IComparer(Of String) Public Function Compare(x As String, y As String) As Integer _ Implements System.Collections.Generic.IComparer(Of String).Compare 'xがyより小さいときはマイナスの数、大きいときはプラスの数、同じときは0を返すようにする Dim aryX As String() = x.Split("/"c) Dim aryY As String() = y.Split("/"c) Dim xDateString As String xDateString = aryX(0).PadLeft(4, "0") xDateString += If(aryX.Length > 1, aryX(1).PadLeft(2, "0"), "00") xDateString += If(aryX.Length > 2, aryX(2).PadLeft(2, "0"), "00") Dim yDateString As String yDateString = aryY(0).PadLeft(4, "0") yDateString += If(aryY.Length > 1, aryY(1).PadLeft(2, "0"), "00") yDateString += If(aryY.Length > 2, aryY(2).PadLeft(2, "0"), "00") Dim i As Integer = xDateString.CompareTo(yDateString) Return i End Function End ClassOrderyByメソッドの第二引数にICompareを実装したCompareDateStringを指定します。
【C#】
string[] dateStrings = { "2015/1/1", "2015/11/11", "2015/5/31", "2015/4", "20" }; //普通に昇順でソート var orderedList1 = dateStrings.OrderBy(str => str); //出力 foreach (var itm in orderedList1) Console.WriteLine(itm); //20 //2015/1/1 //2015/11/11 //2015/4 //2015/5/31 //第二引数にICompareを実装したCompareDateStringを指定しソート var orderedList2 = dateStrings.OrderBy(str => str, new CompareDateString()); //出力 foreach (var itm in orderedList2) Console.WriteLine(itm); //20 //2015/1/1 //2015/4 //2015/5/31 //2015/11/11【VB】
Dim dateStrings As String() = {"2015/1/1", "2015/11/11", "2015/5/31", "2015/4", "20"} '普通に昇順でソート Dim orderedList1 = dateStrings.OrderBy(Function(str) str) For Each itm In orderedList1 Console.WriteLine(itm) Next '20 '2015/1/1 '2015/11/11 '2015/4 '2015/5/31 '第二引数にICompareを実装したCompareDateStringを指定しソート Dim orderedList2 = dateStrings.OrderBy(Function(str) str, New CompareDateString()) For Each itm In orderedList2 Console.WriteLine(itm) Next '20 '2015/1/1 '2015/4 '2015/5/31 '2015/11/11※VBの場合、コンパイルオプションで「Option Infer」をONにし、型推論を有効にしてください。
.Net(VB C#) LINQのメソッド一覧
0 件のコメント:
コメントを投稿