I'm using C# in .NET 4. The class holds an array of double
that represents a 2-D rectangular matrix but (due to business requirements) must be stored flattened (i.e. a double[]
). The class also stores the dimensions of the array. I wish to sort the array by the (virtual) first column. Obviously I have to unflatten it, at least partially, in order to do this, right? I don't see anything in LINQ or System.Array
that works on a flattened array.
If there's 1 column, System.Array.Sort()
works fine and I don't think it can be improved.
If there's 2 columns, it's not hard to split it into two arrays and again use System.Array.Sort()
. If you quickly see a way to improve it great, but if not, I'm happy with it as it stands.
I'm not happy with the code for 3 or more columns (it stinks) and suspect there's some way to improve it.
N.B. In real life the class has get-only properties. It's guaranteed that rows
and cols
are positive, array != null
, and rows*cols==array.Length
.
public partial class FlattenedArray
{
public int rows;
public int cols;
public double[] array;
public void sort()
{
double[] keys;
switch(cols)
{
case 1:
System.Array.Sort<double>(array);
break;
case 2:
keys = new double[rows];
double[] dItems = new double[rows];
for (int i=0,k=0; i<rows; i++)
{
keys[i] = array[k++];
dItems[i] = array[k++];
}
System.Array.Sort<double,double>(keys,dItems);
for (int i=0,k=0; i<rows; i++)
{
array[k++] = keys[i];
array[k++] = dItems[i];
}
break;
default:
keys = new double[rows];
int[] items = new int[rows];
double[] temp = new double[rows*cols];
for (int i=0,k=0; i<rows; i++, k+=cols)
{
keys[i] = array[k];
items[i] = k;
}
System.Array.Sort<double,int>(keys,items);
for (int i=0,k=0; i<rows; i++)
{
int spt = items[i];
for (int j = 0; j < cols; j++)
{
temp[k++] = array[spt++];
}
}
array = temp;
break;
}