- 1. 概要
- 2. 自身を単純ソート
- 3. ソートして別のリストへ
1. 概要
複数の要素が存在するならば、並べたくなるのが、人情ってもんです。
そのせいか、ソートの手法には、複数の方法があるようです。
本ページは、下記のサイトを参考にさせていただきました。
「C# リストで複数キーを指定したソート方法」
2. 自身を単純ソート
ソートに使用する要素が一つであり、自身をソートする場合は
List.Sort((要素1, 要素2) => 要素1 と 要素2 を比較する演算);
と書きます。
「要素1 と 要素2 を比較する演算」は、結果が、正数にならなければなりません。
なので、「int」であれば、減算で十分ですが、「double」であれば「Math.Sign()」を使わなければならないし、「string」であれば、「string.Compare()」を使うなどの工夫が必要になります。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class TestConTains
{
[Serializable]
public class myClass
{
public int i = 0; // 数値型要素
public string s = String.Empty; // 文字列型要素
}
static public void Main ()
{
List<myClass> list = new List<myClass>
{
new myClass { i = 2, s = "Y" },
new myClass { i = 1, s = "Z" },
new myClass { i = 3, s = "X" },
};
list.Sort((a, b) => a.i - b.i);
foreach (myClass item in list)
{
Console.WriteLine("["+ item.i +"] ["+ item.s +"]");
}
Console.WriteLine("");
list.Sort((a, b) => string.Compare(a.s, b.s));
foreach (myClass item in list)
{
Console.WriteLine("["+ item.i +"] ["+ item.s +"]");
}
Console.WriteLine("");
list.Sort((a, b) => a.i - b.i);
myClass first = list.First();
myClass last = list.Last();
Console.WriteLine("first ["+ first.i +"] ["+ first.s +"]");
Console.WriteLine("last ["+ last.i +"] ["+ last.s +"]");
}
}
てなソースを書いて、コンパイル後、実行すると下記の結果が得られます。
[1] [Z]
[2] [Y]
[3] [X]
[3] [X]
[2] [Y]
[1] [Z]
first [1] [Z]
last [3] [X]
尚、43、44行目の「First」「Last」を使うために、4行目の「using System.Linq;」は必要です。
ソートする要素が、複数存在する場合は、別途、比較メソッドが必要なのですが、書く機会があれば、そのうち書きます。
3. ソートして別のリストへ
「OrderBy」に代表されるメソッドを使用して、「List」をソートしたものを「IOrderedEnumerable」で定義する別のリストへ移すことができます。
参考サイトに、「遅延実行されるため、戻り値に対して「foreach」等で列挙操作を行うまではソートされない」と書いてあるのが、いささ気になりますが。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class MyMain
{
[Serializable]
public class myClass
{
public int i = 0; // 数値型要素
public string s = String.Empty; // 文字列型要素
}
static public void Main ()
{
List<myClass> list = new List<myClass>
{
new myClass { i = 2, s = "Y" },
new myClass { i = 1, s = "Z" },
new myClass { i = 3, s = "X" },
new myClass { i = 5, s = "Y" },
new myClass { i = 2, s = "X" },
new myClass { i = 2, s = "Z" },
};
IOrderedEnumerable<myClass> list01 = list.OrderBy(x => x.i).ThenBy(x => x.s);
foreach (myClass item in list01)
{
Console.WriteLine("["+ item.i +"] ["+ item.s +"]");
}
Console.WriteLine("");
IOrderedEnumerable<myClass> list02 = list.OrderByDescending(x => x.s).ThenByDescending(x => x.i);
foreach (myClass item in list02)
{
Console.WriteLine("["+ item.s +"] ["+ item.i +"]");
}
}
}
てなソースを書いて、コンパイル後、実行すると下記の結果が得られます。
[1] [Z]
[2] [X]
[2] [Y]
[2] [Z]
[3] [X]
[5] [Y]
[Z] [2]
[Z] [1]
[Y] [5]
[Y] [2]
[X] [3]
[X] [2]
最初に、数値昇順、文字昇順でソートした結果、次に、文字降順、数値降順でソートした結果を出力しています。
「OrderBy」で最優先するもの、「ThenOrderby」で以降の要素の比較をつなげています。
「...Descending」が、降順になります。
これらのメソッドを、参考サイトのまるパクリで説明しておくと。
| メソッド | 意味 | 備考 |
| OrderBy | 第一優先の要素を昇順ソート | |
| OrderByDescending | 第一優先の要素を降順ソート | |
| ThenBy | 第二優先以降の要素を昇順ソート | |
| ThenByDescending | 第二優先以降の要素を降順ソート | |
てなことになります。
この場合、「string」もうまいことソートされているのでありがたい。
|