I'm a fan of Linq and extension methods for things like this. So, how does this look to you?
public static class MultiDimensionalArrayExtensions
{
public static T[,] OrderBy<T>(this T[,] source, Func<T[], T> keySelector)
{
return source.ConvertToSingleDimension().OrderBy(keySelector).ConvertToMultiDimensional();
}
public static T[,] OrderByDescending<T>(this T[,] source, Func<T[], T> keySelector)
{
return source.ConvertToSingleDimension().
OrderByDescending(keySelector).ConvertToMultiDimensional();
}
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;
}
}
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.
Since I've begun my profession as a software developer, I've learned one important fact - change is inevitable. Requirements change, code changes, and life changes.
So..If you're not moving forward, you're moving backwards.