How To Sort Two Dimensional Array In C# By Selected Column Index In Selected Column Sort Order

Introduction

Almost every program I have created needs a method for sorting a two-dimensional array by column one in the selected sort order, then by column two in the selected sort order, and then by column three in selected sort order ... then by column n in the selected sort order.

For sorting two-dimensional arrays containing different types of values, integers, strings, booleans, etc., I have used DataGridView class and its DataGridViewSort event handler. It is easy to manipulate with data in any way and offers fast sorting as well. An article about that can be found here.

But sometimes, it is not possible to implement such a solution. So, I have made the decision to try to write my own universal method for sorting 2D arrays, that could be used for sorting arrays in any future program that I am going to write.

After a while, I have written this method.

/// <summary>      
/// Sorts two dimensional array type of string,      
/// by selected culumns, in selected sort order.      
/// Selection Sort Algorithm is implemented      
/// for sorting values inside array.      
/// </summary>      
/// <param name="array">      
/// Two dimensional array, type of string,      
/// contaning values that are going to be sorted.      
/// </param>      
/// <param name="sort_directive">      
/// Two dimensional array, type of int.      
/// First column contains the order of the column indexes      
/// by which the array will be sorted.      
/// Second column contains column sort order.      
/// Sort order for each column is defined by ineger values :      
/// -1 - sort column values in Descending sort order      
///  0 - column is not going to be sorted      
///  1 - sort column values in Ascending sort order      
/// </param>      
/// <returns>      
/// Sorted array by selected columns in selected sort order.      
/// </returns>      
public string[,] Sort_String(string [,] array, int [,] sort_directive)      
{      
    // number of rows iside array      
    int array_rows = array.GetLength(0);      
    // number of columns inside array      
    int array_columns = array.Length/array_rows;      
    // number of columns to be sorted      
    int sort_directive_columns = sort_directive.GetLength(0);      
    //      
    for(int i=0;i<array_rows-1;i++)      
    {      
        for(int j=i+1;j<array_rows;j++)      
        {      
            for(int c=0;c<sort_directive_columns;c++)      
            {      
                //      
                // sort array values in descending sort order      
                //      
                if(sort_directive[c,1]==-1 &&      
                   array[i,sort_directive[c,0]].CompareTo(array[j,sort_directive[c,0]])<0)      
                {      
                    //      
                    // if values are in ascending sort order      
                    // swap values      
                    //      
                    for(int d=0;d<array_columns;d++)      
                    {      
                        string h = array[j,d];      
                        array[j,d]=array[i,d];      
                        array[i,d]=h;      
                    }      
                          
                    break;      
                }      
                //      
                // if values are in correct sort order break      
                //      
                else if(sort_directive[c,1]==-1 &&      
                        array[i,sort_directive[c,0]].CompareTo(array[j,sort_directive[c,0]])>0)      
                    break;      
                //      
                // sort array values in ascending sort order      
                //      
                else if(sort_directive[c,1]==1 &&      
                        array[i,sort_directive[c,0]].CompareTo(array[j,sort_directive[c,0]])>0)      
                {      
                    //      
                    // if values are in descending sort order      
                    // swap values      
                    //      
                    for(int d=0;d<array_columns;d++)      
                    {      
                        string h = array[j,d];      
                        array[j,d]=array[i,d];      
                        array[i,d]=h;      
                    }      
                          
                    break;      
                }      
                //      
                // if values are in correct sort order break      
                //      
                else if(sort_directive[c,1]==1 &&      
                        array[i,sort_directive[c,0]].CompareTo(array[j,sort_directive[c,0]])<0)      
                    break;      
                //      
                // if values are equal      
                // select next sort directive     
                //      
            }      
        }      
    }      
          
    return array;      
}

How did I develop this method?

First, the decision was that the 2D array should strictly be the type of string. Since any other type of data (int, double, float, decimal, char, boolean, ...) can be represented as a string value, and because of that, the 2D array type of string could contain diverse types of data that could be easily manipulated and sorted.

Important

Data stored inside the array type of string are always represented (memorized) as a type of String. When sorting, all data are compared as strings, and numbers also. If there is a need to sort numbers, it is necessary to adjust the format of data, so that the sort routine returns the correct result.

numerical data as strings numerical data formated for sorting as number values sorted correctly as numbers
 "1"   "0001"   "0001"
 "10"  "0010"  "0003"
 "214"  "0214"  "0004"
 "3"  "0003"   "0005"
 "4"  "0004"  "0010"
 "5"  "0005"  "0214"
 "1024"  "1024"  "1024"

 

numerical data as strings numerical data not formated for sorting as number values sorted correctly as strings
    "1"  "1"  "1"
  "10"  "10"  "10"
"214"  "214"  "1024"
    "3"  "3"  "214"
   "4"  "4"  "3"
    "5"  "5"  "4"
"1024"  "1024"  "5"

Example of formatting numerical data.

int numerical_data = 100;      
string format = "000000";      
string formated_data = numerical_data.ToString(format);

Result of formatting.

Numerical data  Formatted data

         100                000100

The name of the 2D array inside the program shall be TABLE.

Declaration of TABLE with 10 rows and 10 columns, max 100 elements.

int rows = 10;      
int columns = 10;      
      
string [,] TABLE = new string[rows,columns];

The second decision was to use a 2D array type of integer for storing TABLE sort directives.

A simple sort directive looks like this.

Sort TABLE by Column One in Ascending sort order.

As shown, sort directive consists of selected TABLE column index and its sort order.

So this array should have only two columns. 

The first column shall contain a selected column index.

The second column contains column sort order defined by integer values.

  • - 1 - sort column values in Descending sort order
  •   0 - column is not going to be sorted
  •   1 - sort column values in Ascending sort order

The number of rows depends on how many sort directives are entered by the user.

Name of the 2D array inside program shall be SORT_DIRECTIVE.

Declaration of SORT_DIRECTIVE,

int rows = number of sort directives;      
int columns = 2;      
      
string [,] SORT_DIRECTIVE = new string[rows,columns];

Example of sort directive and SORT_DIRECTIVE element values

TABLE has seven rows and three columns,

  • Sort TABLE by Column One in Ascending sort order then by
  • Column Two in Descending sort order then by
  • Column Three in Ascending sort order.

         SORT_DIRECTIVE

                  1           1
                  2          -1
                  3           1
The third and final decision was the selection of Sort Algorithm.

I have decided to use the Selection Sort Algorithm for its simplicity of implementation. Also, it is fast enough for a small amount of data, up to 1000 records.

How does it work?

Create and fill TABLE with data. Be careful if some column should contain numbers. Numbers must be specially formatted for sorting as described in the important notice above. 

//    
// Create and fill TABLE    
//    
string [,] TABLE = new string[7,3]    
{    
    { "John"     , "Porter"    , "1234 Oak street, Pensacola, FL 32503"         },    
    { "John"     , "Porter"    , "1891 3rd Street North Westlake, OH 44145"     },    
    { "William"  , "Patterson" , "4534 Virginia Street Dallas, GA 30132"        },    
    { "Marry"    , "Cortez"    , "7642 Fairview Avenue Milwaukee, WI 53204"     },    
    { "John"     , "Patterson" , "1368 Street Road Morristown, NJ 07960"        },    
    { "Elizabet" , "Cortez"    , "3698 Cedar Avenue Saratoga Springs, NY 12886" },    
    { "Marry"    , "Mosley"    , "4575 11th Street Sacramento, CA 95820"        }    
        
};

Then, create and fill SORT_DIRECTIVE.   

//    
// Table SORT DIRECTIVE contains order of columns    
// by which array is going to be sorted and sort order    
// for each selected column    
//    
//  0 - do not sort column    
// -1 - sort in Descending order    
//  1 - sort in Ascending order    
//    
int [,] SORT_DIRECTIVE=new int[3,2]    
{    
    {0,  1},    
    {1, -1},    
    {2,  1}    
}; 

Call method.

//  
// Call sort method  
//  
TABLE = Sort_String(TABLE,SORT_DIRECTIVE); 

When finished, method returns sorted array TABLE by values inside SORT_DIRECTIVE.    

//    
// Print sorted TABLE    
//    
Console.WriteLine();    
Console.WriteLine("  SORTED TABLE");    
Console.WriteLine(" --------------");    
Console.WriteLine();    
for(int n=0;n<7;n++)    
{    
    Console.WriteLine("  {0,-10}{1,-10}{2,-10}",TABLE[n,0],TABLE[n,1],TABLE[n,2]);    
}    
Console.WriteLine(" --------------");    
//

Here is the program's screenshot.

 

How To Sort Two Dimensional Array By Selected Column Index In Selected Column Sort Order

Notice
Names and addresses shown in the picture are fictional.

Conclusion

For sorting up to a thousand rows filled with data, this method is almost as fast as DataGridView with its SortEventHandler. If there is a need for sorting more data than that, perhaps by implementing faster sort algorithm, things would be better. This method can easily be changed to sort 2D arrays of any type, inside open source solution there is class Sort_2D_Array containing these methods,

  • Sort_String
  • Sort_Int
  • Sort_Double
  • Sort_Decimal
  • Sort_Float 

Name of the method shows what is the type of array that is going to be sorted.

Download link for open source solution is at the beginning of this article. The archive is called TAS.zip ( two-dimensional array sort ). The solution was created in IDE SharpDevelop and needs .NET 4.0 to work correctly.

Similar Articles