Listのソート (IComparer を用いたカスタムソート) - C#
IComparerを用いたListのカスタムソートのコードを紹介します。
概要
こちらの記事では、Comparisionを実装してクラスオブジェクトのリストをソートするコードを紹介しましたが、
より複雑なソートのロジックを実装する場合は、IComparerインターフェイスを持つソート用のクラスを実装する方法が適しています。
この記事ではIComparer を利用したListのカスタムソートのコードを紹介します。
プログラム例
UI
下図のUIを用意します。テキストボックス1つ、ボタンを1つ設置します。
コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ListSort
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
List<Info> InfoList = new List<Info>();
Info inf;
inf = new Info();
inf.Name = "Penguin";
inf.value = 10;
InfoList.Add(inf);
inf = new Info();
inf.Name = "Duck";
inf.value = 5;
InfoList.Add(inf);
inf = new Info();
inf.Name = "Pigion";
inf.value = 5;
InfoList.Add(inf);
inf = new Info();
inf.Name = "Swallow";
inf.value = 8;
InfoList.Add(inf);
inf = new Info();
inf.Name = "Spallow";
inf.value = 5;
InfoList.Add(inf);
inf = new Info();
inf.Name = "Hawk";
inf.value = 18;
InfoList.Add(inf);
ValueCompare vc = new ValueCompare();
InfoList.Sort(vc);
for (int i = 0; i < InfoList.Count; i++) {
textBox_Output.Text += string.Format("{0:s}:{1:d}\r\n",
InfoList[i].Name, InfoList[i].value);
}
}
}
}
infoクラスの実行コードです。Nameとvalueのメンバ変数を定義しています。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListSort
{
public class Info
{
public string Name;
public int value;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListSort
{
public class ValueCompare : System.Collections.Generic.IComparer<Info>
{
public int Compare(Info x, Info y)
{
if (x.value < y.value) {
return -1;
}
else if (x.value > y.value) {
return 1;
}
else {
if (x.Name.Length < y.Name.Length) {
return -1;
}
else if (x.Name.Length > y.Name.Length) {
return 1;
}
else {
return 0;
}
}
}
}
}
解説
FormMain.cs
List<Info> InfoList = new List<Info>();
InfoクラスのListを宣言してインスタンスを作成します。
inf = new Info();
inf.Name="Penguin";
inf.value=100;
InfoList.Add(inf);
...
にて、InfoListにInfoクラスの要素を追加します。
ValueCompare vc = new ValueCompare();
InfoList.Sort(Compare);
リストをソートします。引数のIComparerにICompaererのインターフェイスを持つクラスのインスタンスを与えます。
for (int i = 0; i < InfoList.Count; i++ ) {
textBox_Output.Text += string.Format("{0:s}:{1:d}\r\n",
InfoList[i].Name, InfoList[i].value);
}
InfoListの要素を先頭から順番にTextBoxに表示します。
info.cs
IComparerインターフェイスを持つクラスを宣言します。
public class ValueCompare : System.Collections.Generic.IComparer<Info>
ValueCompare.cs
以下のコードがソートの比較用メソッドです。valueの値の昇順にソートします。valueが同じ場合はNameの文字数で昇順にソートします。
public int Compare(Info x, Info y)
{
if (x.value < y.value) {
return -1;
}
else if (x.value > y.value) {
return 1;
}
else {
if (x.Name.Length < y.Name.Length) {
return -1;
}
else if (x.Name.Length > y.Name.Length) {
return 1;
}
else {
return 0;
}
}
}
実行結果
アプリケーションを実行すると下図の画面が表示されます。
コードを実装したボタン(今回の場合は[Exec3])をクリックします。下図の結果がテキストボックスに表示されます。valueの値で昇順にvalueが同じ値の場合はNameの文字数で昇順にソートされていることを確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用