0

How can I sort a 2D array in C#

I have looked at other answers to this question but they don't do exactly what I need.

The array is variable height * 5 across

The array holds strings

I need the array sorted based on either column, for example sort in alphabetical the third column, however all other columns must be updated.

Does anyone know of a quick and easy solution?

My code is a mess, here is a shortened version:

string[,] tmp = new string[2, 3];//this is filled with strings
string y = Console.ReadLine();
int x = Convert.ToInt32(y);

// sort tmp based on x column
Joseph
  • 3,899
  • 10
  • 33
  • 52
  • 1
    Is it a jagged array or a multidimensional array? – Nick Larsen Apr 08 '13 at 14:41
  • @NickLarsen its multidimensional, each row always has columns filled – Joseph Apr 08 '13 at 14:46
  • Can you use LINQ this works for me using LINQ arrayName.OrderBy(item => item[0]).ToArray(). Ordering Descending is arrayName.OrderByDescending(item => item[0]).ToArray(). – TheKingDave Apr 08 '13 at 14:47
  • Do you _need_ to use an array? A sorting routine that can reorder _references_ is likely to be much faster that reordering _values_, which you'll have to do to sort the array in-place. – D Stanley Apr 08 '13 at 15:07
  • @DStanley I'll have to research into references, I've never heard of them before. – Joseph Apr 08 '13 at 16:49

2 Answers2

1

How do I sort a two-dimensional array in C#? contains a possible solution to this by reading your data into a datatable and then using the object's methods to sort:

// assumes stringdata[row, col] is your 2D string array
DataTable dt = new DataTable();
// assumes first row contains column names:
for (int col = 0; col < stringdata.GetLength(1); col++)
{
    dt.Columns.Add(stringdata[0, col]);
}
// load data from string array to data table:
for (rowindex = 1; rowindex < stringdata.GetLength(0); rowindex++)
{
    DataRow row = dt.NewRow();
    for (int col = 0; col < stringdata.GetLength(1); col++)
    {
        row[col] = stringdata[rowindex, col];
    }
    dt.Rows.Add(row);
}
// sort by third column:
DataRow[] sortedrows = dt.Select("", "3");
// sort by column name, descending:
sortedrows = dt.Select("", "COLUMN3 DESC");
Community
  • 1
  • 1
Ken de Jong
  • 219
  • 1
  • 11
  • Is sortedrows a array? or do I have to convert, I have seen this answer before but it confused me. Does this convert back into a array? – Joseph Apr 08 '13 at 14:47
  • basically what this does is read all your data into a datatable on which you can perform functions. If you want an array out of this you should convert it back to an array after sorting or doing whatever functions you want to perform on the dataset – Ken de Jong Apr 08 '13 at 14:53
  • Thanks, i'll give it a go. :) Can I convert the final dataset back into a array via `string[,] newArray = sortedrows;` Or do I have to use a method to do this? – Joseph Apr 08 '13 at 14:55
  • If i am correct you can convert the datatable back to an array with toArray() – Ken de Jong Apr 08 '13 at 15:01
1

So first we'll want to convert the multi-dimensional array into a sequence of single-dimensional arrays representing the rows, so that each row can be manipulated as a unit:

public static IEnumerable<T[]> GetRows<T>(T[,] array)
{
    for (int i = 0; i < array.GetLength(0); i++)
    {
        T[] row = new T[array.GetLength(1)];
        for (int j = 0; j < row.Length; j++)
        {
            row[j] = array[i, j];
        }
        yield return row;
    }
}

Then we'll also need a method that does the reverse to get a multi-dimensional array back when we're done:

public static T[,] ToMultiDimensionalArray<T>(T[][] rows)
{
    T[,] output = new T[rows.Length, rows[0].Length];

    for (int i = 0; i < rows.Length; i++)
        for (int j = 0; j < rows[0].Length; j++)
        {
            output[i, j] = rows[i][j];
        }
    return output;
}

Now we just need to sort a sequence of arrays, and Linq makes this quite easy:

tmp = ToMultiDimensionalArray(GetRows(tmp)
    .OrderBy(row => row[2]).ToArray());
Servy
  • 202,030
  • 26
  • 332
  • 449
  • Thanks for this, I'll give this a go too. I never had any idea sorting a 2D array could be so odd, I really thought C# would have had a built in method for this sort of this. Cheers :) – Joseph Apr 08 '13 at 16:51
  • @Joseph The issue is that you want to treat the 2D array by it's rows, rather than as each of the values. If you had a jagged array to start with then it would be a better fit as it's logically a collection of collections, and you can sort those rows as logical units. I wouldn't expect the language to provide this type of sorting mechanism. – Servy Apr 08 '13 at 16:54