Sorting a Two-Dimensional Array in C#






4.96/5 (11 votes)
How to sort a two-dimensional array in C#
I'm a fan of Linq and extension methods for things like this. So, how does this look to you?
public static class MultiDimensionalArrayExtensions
{
/// <summary>
/// Orders the two dimensional array by the provided key in the key selector.
/// </summary>
/// <typeparam name="T">The type of the source two-dimensional array.</typeparam>
/// <param name="source">The source two-dimensional array.</param>
/// <param name="keySelector">The selector to retrieve the column to sort on.</param>
/// <returns>A new two dimensional array sorted on the key.</returns>
public static T[,] OrderBy<T>(this T[,] source, Func<T[], T> keySelector)
{
return source.ConvertToSingleDimension().OrderBy(keySelector).ConvertToMultiDimensional();
}
/// <summary>
/// Orders the two dimensional array by the provided key in the key selector in descending order.
/// </summary>
/// <typeparam name="T">The type of the source two-dimensional array.</typeparam>
/// <param name="source">The source two-dimensional array.</param>
/// <param name="keySelector">The selector to retrieve the column to sort on.</param>
/// <returns>A new two dimensional array sorted on the key.</returns>
public static T[,] OrderByDescending<T>(this T[,] source, Func<T[], T> keySelector)
{
return source.ConvertToSingleDimension().
OrderByDescending(keySelector).ConvertToMultiDimensional();
}
/// <summary>
/// Converts a two dimensional array to single dimensional array.
/// </summary>
/// <typeparam name="T">The type of the two dimensional array.</typeparam>
/// <param name="source">The source two dimensional array.</param>
/// <returns>The repackaged two dimensional array as a single dimension based on rows.</returns>
private static IEnumerable<T[]> ConvertToSingleDimension<T>(this T[,] source)
{
T[] arRow;
for (int row = 0; row < source.GetLength(0); ++row)
{
arRow = new T[source.GetLength(1)];
for (int col = 0; col < source.GetLength(1); ++col)
arRow[col] = source[row, col];
yield return arRow;
}
}
/// <summary>
/// Converts a collection of rows from a two dimensional array back into a two dimensional array.
/// </summary>
/// <typeparam name="T">The type of the two dimensional array.</typeparam>
/// <param name="source">The source collection of rows to convert.</param>
/// <returns>The two dimensional array.</returns>
private static T[,] ConvertToMultiDimensional<T>(this IEnumerable<T[]> source)
{
T[,] twoDimensional;
T[][] arrayOfArray;
int numberofColumns;
arrayOfArray = source.ToArray();
numberofColumns = (arrayOfArray.Length > 0) ? arrayOfArray[0].Length : 0;
twoDimensional = new T[arrayOfArray.Length, numberofColumns];
for (int row = 0; row < arrayOfArray.GetLength(0); ++row)
for (int col = 0; col < numberofColumns; ++col)
twoDimensional[row, col] = arrayOfArray[row][col];
return twoDimensional;
}
}
Then, to be able to use the code above, you would simply do something like the following:
int[,] array = new int[3, 3] { { 1, 4, 2 }, { 4, 5, 1 }, { 7, 3, 8 } };
int[,] sortedByFirstElement = array.OrderBy(x => x[0]);
int[,] sortedBySecondElement = array.OrderBy(x => x[1]);
int[,] sortedByThirdElement = array.OrderBy(x => x[2]);
The keyselector Func
is merely the way to determine the column to sort on using lambdas.