patterncsharpMinor
Sorting a flattened array
Viewed 0 times
arraysortingflattened
Problem
I'm using C# in .NET 4. The class holds an array of
If there's 1 column,
If there's 2 columns, it's not hard to split it into two arrays and again use
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
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(array);
break;
case 2:
keys = new double[rows];
double[] dItems = new double[rows];
for (int i=0,k=0; i(keys,dItems);
for (int i=0,k=0; i(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;
}Solution
You can improve the code for 3 or more columns and at the same time use it for 1 or 2 columns, by using LINQ:
This divides the array into dimensions and sorts it by the first column then flattens it all back to 1D. It will work for any combination of rows and columns as long the conditions you mentioned hold true.
If the data size gets very large you still might want to use Array.Sort for the 1 column data as this code wouldn't be very efficient for 1 column.
public partial class FlattenedArray
{
public int rows;
public int cols;
public double[] array;
public void sort()
{
array = (from i in Enumerable.Range(0, rows)
select new List(array.ToList().GetRange(cols * i, cols)))
.OrderBy(x => x[0])
.SelectMany(x => x)
.ToArray();
}
}This divides the array into dimensions and sorts it by the first column then flattens it all back to 1D. It will work for any combination of rows and columns as long the conditions you mentioned hold true.
If the data size gets very large you still might want to use Array.Sort for the 1 column data as this code wouldn't be very efficient for 1 column.
Code Snippets
public partial class FlattenedArray
{
public int rows;
public int cols;
public double[] array;
public void sort()
{
array = (from i in Enumerable.Range(0, rows)
select new List<double>(array.ToList().GetRange(cols * i, cols)))
.OrderBy(x => x[0])
.SelectMany(x => x)
.ToArray();
}
}Context
StackExchange Code Review Q#51259, answer score: 5
Revisions (0)
No revisions yet.