Listのソート (IComparable を用いたカスタムソート) - C#
IComparable を用いたListのカスタムソートのコードを紹介します。
概要
クラスオブジェクト(List<T>)のリストをソートする場合、オブジェクトの大小関係を判定する必要があります。
IComparable インターフェイスを利用して、CompareTo メソッドを実装すると、オブジェクトの大小関係を判定するロジックを実装でき、
Sortメソッドでオブジェクトのリストをソートできます。
この記事では、IComparable インターフェイスとCompareToメソッドの実装手順を紹介します。
プログラム例
Windows Formアプリケーションを作成し、以下のコードを記述します。
UI
下図のフォームを作成します。ボタンとテキストボックスを配置します。
コード
以下のコードを記述します。
namespace ListSortComparable
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<MyItem> mlist = new List<MyItem>();
mlist.Add(new MyItem() { id = 2, itemname = "らくだキャラメル", price = 80, stocks = 45, category = 2 });
mlist.Add(new MyItem() { id = 1, itemname = "ぺんぎんクッキー", price = 160, stocks = 25, category = 1 });
mlist.Add(new MyItem() { id = 8, itemname = "ももんがマシュマロ", price = 100, stocks = 32, category = 1 });
mlist.Add(new MyItem() { id = 3, itemname = "しろくまアイス", price = 280, stocks = 12, category = 3 });
mlist.Add(new MyItem() { id = 4, itemname = "かるがもサブレ", price = 140, stocks = 6, category = 1 });
mlist.Add(new MyItem() { id = 6, itemname = "きつつきキャンディ", price = 50, stocks = 18, category = 2 });
mlist.Add(new MyItem() { id = 5, itemname = "くじらロールケーキ", price = 680, stocks = 4, category = 1 });
mlist.Add(new MyItem() { id = 7, itemname = "あるぱかグミ", price = 20, stocks = 28, category = 2 });
for (int i = 0; i < mlist.Count; i++) {
textBox1.Text += string.Format("ID:{0:d} name:{1} price:{2:d} stocks:{3:d} category:{4:d}\r\n",
mlist[i].id, mlist[i].itemname, mlist[i].price, mlist[i].stocks, mlist[i].category);
}
textBox1.Text += "------\r\n\r\n";
mlist.Sort();
for (int i = 0; i < mlist.Count; i++) {
textBox1.Text += string.Format("ID:{0:d} name:{1} price:{2:d} stocks:{3:d} category:{4:d}\r\n",
mlist[i].id, mlist[i].itemname, mlist[i].price, mlist[i].stocks, mlist[i].category);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ListSortComparable
{
public class MyItem: IComparable<MyItem>
{
public int id;
public string itemname="";
public int price;
public int stocks;
public int category;
public int CompareTo(MyItem? other)
{
if (other != null) {
if (id == other.id) {
return 0;
}
else if (id < other.id) {
return -1;
}
else {
return 1;
}
}
else {
return 0;
}
}
}
}
解説
MyItem.cs
カスタムのソートのロジックを実装したMyItemクラスを作成します。
カスタムのソートロジックの
CompareTo()
メソッドをオーバーライドするため、
作成するクラスは、
IComparable<MyItem>
インターフェイスを実装します。
public class MyItem: IComparable<MyItem>
クラスにCompareToメソッドをオーバーライドして実装します。
今回の例では、メンバ変数
id
の値の大小で2つのMyItemオブジェクトの大小を決定するロジックを実装しています。
public int CompareTo(MyItem? other)
{
if (other != null) {
if (id == other.id) {
return 0;
}
else if (id < other.id) {
return -1;
}
else {
return 1;
}
}
else {
return 0;
}
}
フォーム
List<MyItem>
オブジェクトを作成し、MyItemオブジェクトを作成し、値を設定しリストに追加して元データを作成します。
List<MyItem> mlist = new List<MyItem>();
mlist.Add(new MyItem() { id = 2, itemname = "らくだキャラメル", price = 80, stocks = 45, category = 2 });
mlist.Add(new MyItem() { id = 1, itemname = "ぺんぎんクッキー", price = 160, stocks = 25, category = 1 });
mlist.Add(new MyItem() { id = 8, itemname = "ももんがマシュマロ", price = 100, stocks = 32, category = 1 });
mlist.Add(new MyItem() { id = 3, itemname = "しろくまアイス", price = 280, stocks = 12, category = 3 });
mlist.Add(new MyItem() { id = 4, itemname = "かるがもサブレ", price = 140, stocks = 6, category = 1 });
mlist.Add(new MyItem() { id = 6, itemname = "きつつきキャンディ", price = 50, stocks = 18, category = 2 });
mlist.Add(new MyItem() { id = 5, itemname = "くじらロールケーキ", price = 680, stocks = 4, category = 1 });
mlist.Add(new MyItem() { id = 7, itemname = "あるぱかグミ", price = 20, stocks = 28, category = 2 });
List<MyItem>
オブジェクトを順にテキストボックスに表示します。
for (int i = 0; i < mlist.Count; i++) {
textBox1.Text += string.Format("ID:{0:d} name:{1} price:{2:d} stocks:{3:d} category:{4:d}\r\n",
mlist[i].id, mlist[i].itemname, mlist[i].price, mlist[i].stocks, mlist[i].category);
}
textBox1.Text += "------\r\n\r\n";
Sort()
メソッドを実行して、リストをソートします。
mlist.Sort();
ソート後のリストの値をテキストボックスに表示します。
for (int i = 0; i < mlist.Count; i++) {
textBox1.Text += string.Format("ID:{0:d} name:{1} price:{2:d} stocks:{3:d} category:{4:d}\r\n",
mlist[i].id, mlist[i].itemname, mlist[i].price, mlist[i].stocks, mlist[i].category);
}
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
[button1]をクリックします。テキストボックスに下図の結果が表示されます。
前半の出力は、リストに追加した順番に値が表示されていますが、
後半の出力は、ID値が昇順に表示され、Sortメソッドの呼び出しにより、
MyItemオブジェクトの
CompareTo()
メソッドが実行され、IDの値順にソートされた動作が確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用