WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

C# Listを自由に並び替える

今回のエンジニアブログを担当する加賀です。

C#のリスト内のデータを様々な条件で並び替える方法を書いておきます。
今回のコード等はVS2010 Pro SP1、C# .NET Framework 2.0で確認しています。

ListSortメソッドは、以下の4通り存在しています。

void Sort()  
void Sort(Comparison comparison)  
void Sort(IComparer comparer)  
void Sort(int index, int count, IComparer comparer)  

1つ目ではリストのデータ型のデフォルト比較演算子で、比較が行われて並び替えされますが、
今回は2つ目の方法を使います。

Comparisonとは簡単にいうと同じ型の変数2つの比較を行う関数です。

public delegate int Comparison<T> ( T a, T b )

また、Comparisonの戻り値は以下のとおりにします。

戻り値条件
0 より小さいa が b より小さい
0a と b が同じ
0 より大きいa が b より大きい

これを並び替えのルールごとに作成します。
例えば、IDの昇順・降順、名前の昇順・降順…というように作成していきます。

並び替え対象

今回、リストのデータとして以下のクラスを使用します。

//Listの要素クラス  
public class Data  
{  
    public int ID;  
    public string Name;  
    public int HP;  
    public int Atk;  
    public int Def;  
  
    //コンストラクタ  
    public Data(int ID, string Name, int HP, int Atk, int Def)  
    {  
        this.ID = ID;  
        this.Name = Name;  
        this.HP = HP;  
        this.Atk = Atk;  
        this.Def = Def;  
    }  
}  

このクラス内に比較関数を追加していきます。

//ID昇順  
public static int CompareIDAsc(Data a, Data b)  
{  
    // nullチェック  
    if (a == null) {  
        if (b == null) {  
            return 0;  
        }  
        return -1;  
    } else {  
        if (b == null) {  
            return 1;  
        }  
  
        // aとbの比較  
        return a.ID.CompareTo (b.ID);  
    }  
}  
  
//ID降順  
public static int CompareIDDesc(Data a, Data b)  
{  
    // nullチェック  
    if (a == null) {  
        if (b == null) {  
            return 0;  
        }  
        return 1;  
    } else {  
        if (b == null) {  
            return -1;  
        }  
  
        // bとaの比較  
        return b.ID.CompareTo (a.ID);  
    }  
}  
  
...以下省略  

何か特別な処理をしなければこれだけで比較関数は終わりです。nullチェックを念のために入れておきました。

また、降順に並び替えるには、昇順の正反対の値を返す必要がありますが、上のコードでは
return文の「a」と「b」を入れ替えるだけで、正反対の値を返すことができ、降順に並び替わります。

実際に並び替える

結果が見やすく、並び替え操作もしやすいように以下のようなフォームを作成しました。

フォーム画像

右下のソートボタンが押されたときに、左下の昇順・降順のラジオボタンの選択状況に応じて、
それぞれの項目をどちらの順序で並び替えるかを判断しています。

今回はソートボタン「ID」の処理を紹介します。ほかの4つも全く同じ構成になっています。

private void buttonID_Click(object sender, EventArgs e)  
{  
    if (radioButtonAsc.Checked) {  
        // 昇順  
        DataList.Sort (Data.CompareIDAsc);  
    } else {  
        // 降順  
        DataList.Sort (Data.CompareIDDesc);  
    }  
  
    //テキストボックス更新  
    DataList_Output();  
}  

並び替え処理自体も簡単で、Sort関数の引数に、Dataクラス内で作成していた比較関数を()を付けずに書くだけです。

ここで、降順のラジオボタンにチェックがある状態で、HPボタンを押してみると…

HP降順並び替え後

きちんとHPの降順で並び替えが行われました!

ちょっとした技でもない小技でしたが、1つのデータ型に対して複数の並び替えを行いたい場合に役に立つと思います。
最後に今回作成したプロジェクトをアップロードしておきます。
ListSort.zip