[[ C#小技巧系列 - 編程 ]] [[ 排序多維陣列 ]] 例如有個兩維陣列: 1, 6, 7 2, 5, 9 3, 4, 8 如果把它想像成一個Table,當 order by 第2欄 desc 之後,就會變成: 2, 5, 9 3, 4, 8 1, 6, 7 C# 有兩種Array:Jagged Array和Rectangular Array。 Jagged Array其實是個Array of Array,所以只要用 IComparer來定義排序方式便可。 /// using System; using System.Collections; public enum SortOrder { Ascending ,Descending } public class JaggedComparer: IComparer { private int m_SortColumn; private SortOrder m_SortOrder; public JaggedComparer(int column, SortOrder order) { m_SortColumn = column; m_SortOrder = order; } public JaggedComparer(int column) : this(column, SortOrder.Ascending) { } public JaggedComparer() : this(0) { } public int Compare(object x, object y) { int[] ax = (int[]) x; int[] ay = (int[]) y; int result; result = ax[m_SortColumn].CompareTo( ay[m_SortColumn] ); if (m_SortOrder == SortOrder.Descending) { result *= -1; } return result; } } class MainClass { static void Main() { int[][] a = new int[][] { new int[]{1, 6, 7} ,new int[]{2, 5, 9} ,new int[]{3, 4, 8} }; Dump2dJaggedArray(a); Array.Sort(a, new JaggedComparer(2, SortOrder.Descending)); Dump2dJaggedArray(a); } public static void Dump2dJaggedArray( int[][] array) { foreach ( int[] i in array ) { foreach ( int j in i ) { Console.Write( "{0},", j ); } Console.WriteLine(); } Console.WriteLine(); } } /// 至於Rectangular Array,我們可以用間接的方法: /// using System; using System.Collections; public enum SortOrder { Ascending ,Descending } public class RectangularComparer: IComparer { private int[,] m_OriginalArray; private int m_SortColumn; private SortOrder m_SortOrder; public RectangularComparer(int column, SortOrder order, int[,] array) { m_SortColumn = column; m_SortOrder = order; m_OriginalArray = array; } public RectangularComparer(int column, int[,] array) : this(column, SortOrder.Ascending, array) { } public RectangularComparer(int[,] array) : this(0, array) { } public int Compare(object x, object y) { int rx = (int) x; int ry = (int) y; int result; result = m_OriginalArray[rx, m_SortColumn].CompareTo( m_OriginalArray[ry, m_SortColumn] ); if (m_SortOrder == SortOrder.Descending) { result *= -1; } return result; } } class MainClass { static void Main() { int[,] a = new int[,] { {1, 6, 7} ,{2, 5, 9} ,{3, 4, 8} }; int[] rowOrder0 = new int[]{0, 1, 2}; int[] rowOrder2 = new int[]{0, 1, 2}; Array.Sort( rowOrder0, new RectangularComparer(0, SortOrder.Descending, a) ); Array.Sort( rowOrder2, new RectangularComparer(2, SortOrder.Descending, a) ); Dump2dRectangularArray(rowOrder0, a); Dump2dRectangularArray(rowOrder2, a); } public static void Dump2dRectangularArray( int[] pRowOrder, int[,] pArray) { for (int i = 0; i < pRowOrder.Length; i++) { for (int j = 0; j <= pArray.GetUpperBound(1); j++) { Console.Write("{0},", pArray[pRowOrder[i], j] ); } Console.WriteLine(); } Console.WriteLine(); } } /// 用一個額外的一維陣列 rowOrder2 去儲存行號 0, 1, 2, 當排序時,就排序這個一維陣列。 當存取原本陣列時,就用 rowOrder2 來間接地存取它。 這種間接方式的優點是可以建立多種排序方式, 例如 rowOrder0和rowOrder2,但不用移動原本陣列。 它也可以排序Jagged Array。