まず、Array.Sortメソッドを使用して任意の型をソートする際、ソート対象に加えソート対象の要素同士の比較を行うメソッド(comparer)を指定する必要があります。 要素の比較を行うメソッドでは、引数として渡される二つの要素xとyについて、その大小関係に従って次のような値を返すように実装する必要があります。
- x > y ならば 正の数
- x < y ならば 負の数
- x = y ならば 0
ジャグ配列のソートの場合、ジャグ配列内の各配列を比較して並べ替えることになるため、要素xとyはジャグ配列内の各配列となります。 また、ジャグ配列の場合はそれぞれ長さの異なる配列を含めることができるため、ここでは二つの配列の大小関係を次のように定めることにします。
- 二つの配列x, yの長さのうち、小さい方の長さをminとする (min = Math.Min(x.Length, y.Length))
- 二つの配列の要素を先頭からmin番目まで一つずつ比較し、n番目の要素について
- x[n] > y[n] ならば x > y とする (正の数を返す)
- x[n] < y[n] ならば x < y とする (負の数を返す)
-
min番目までの要素がすべて同じだった場合、配列x, yの長さについて
- x.Length > y.Length ならば x > y とする (正の数を返す)
- x.Length < y.Length ならば x < y とする (負の数を返す)
- x.Length = y.Length ならば x = y とする (0を返す)
この大小関係に従ってジャグ配列をソートするコードを実装すると、次のようになります。
2段のジャグ配列をソートする
using System;
class Sample {
// 長さが異なる二つの配列を比較するメソッド
// (このメソッドでジャグ配列内の各配列同士を比較する際の動作を定義する)
static int CompareArray(int[] x, int[] y)
{
var min = Math.Min(x.Length, y.Length);
for (var n = 0; n < min; n++) {
if (x[n] > y[n])
return 1;
else if (x[n] < y[n])
return -1;
}
if (x.Length > y.Length)
return 1;
else if (x.Length < y.Length)
return -1;
else /* if (x.Length == y.Length) */
return 0;
}
static void Main()
{
var arr = new int[][] {
new int[] {1, 2},
new int[] {2, 1},
new int[] {2, 1, 1},
new int[] {1, 2, 2, 2},
new int[] {1, 1},
new int[] {1, 3},
new int[] {1, 2, 3},
new int[] {1, 2, 2},
new int[] {2, 2},
new int[] {2, 1, 1},
};
// ソート
Array.Sort(arr, CompareArray);
for (var y = 0; y < arr.Length; y++) {
for (var x = 0; x < arr[y].Length; x++) {
Console.Write("{0}, ", arr[y][x]);
}
Console.WriteLine();
}
}
}
実行結果
1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 1, 2, 3, 1, 3, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2,
このように、2段のジャグ配列(配列の配列)をソートするには配列同士の大小関係を定義して比較する必要があります。 3段以上のジャグ配列の場合も同様で、例えば3段のジャグ配列(配列の配列の配列)なら2段のジャグ配列(配列の配列)同士の大小関係を定義する必要があります。