F.P
F.P

Reputation: 17831

Sorting DataTable-columns

I have a datatable something like this:

     |  Col1  |  Col6  |  Col3  |  Col43 |  Col0  |
---------------------------------------------------
RowA |   1    |    6   |   54   |    4   |   123  |

As you see, the Cols are not sorted by their numbers. That is what I want it to look like after the "magic":

     |  Col0  |  Col1  |  Col3  |  Col6  |  Col43 |
---------------------------------------------------
RowA |   123  |    1   |   54   |    6   |    4   |

Is there a built-in function for such things in C#? And if not, how could I get started with this?

Upvotes: 3

Views: 15926

Answers (6)

Andy
Andy

Reputation: 21

Here's a combination of the preceding answers. Use the built in Sort() method of a List or an Array of strings to sort a list of the column names, then use the DataColumn.SetOrdinal() method to rearrange your DataTable's columns to match the sorted list.

List<string> columnNames = new List<string>();
foreach (DataColumn col in table.Columns)
{
    columnNames.Add(col.ColumnName);
}
columnNames.Sort();

int i = 0;
foreach (string name in columnNames)
{
    table.Columns[name].SetOrdinal(i);
    i++;
}

(Where "table" is the name of your DataTable.)

Upvotes: -1

Daniel Henry
Daniel Henry

Reputation: 856

var columnArray = new DataColumn[table.Columns.Count];
table.Columns.CopyTo(columnArray, 0);
var ordinal = -1;
foreach (var orderedColumn in columnArray.OrderBy(c => c.ColumnName))
    orderedColumn.SetOrdinal(++ordinal);

Upvotes: 2

Ruben G&#170; Ibeas
Ruben G&#170; Ibeas

Reputation: 21

Here is my code, surely not is the best solution but works. In my case I let a fixed column that could be "Nombre" or "Problem", this always be the first in column order.

// class
public class stringInt
{
    public string Nombre;
    public int orden;
}

// function

static public DataTable AlphabeticDataTableColumnSort(DataTable dtTable)
{
    //vamos a extraer todos los nombres de columnas, meterlos en una lista y ordenarlo
    int orden = 1;
    List<stringInt> listaColumnas = new List<stringInt>();

    foreach (DataColumn dc in dtTable.Columns)
    {
        stringInt columna = new stringInt();
        columna.Nombre = dc.Caption;
        if ((dc.Caption != "Problema") && (dc.Caption != "Nombre")) columna.orden = 1;
        else columna.orden = 0;
        listaColumnas.Insert(0,columna);
     }
     listaColumnas.Sort(delegate(stringInt si1, stringInt si2) { return si1.Nombre.CompareTo(si2.Nombre); });

     // ahora lo tenemos ordenado por nombre de columna
     foreach (stringInt si in listaColumnas)
     { 
         // si el orden es igual a 1 vamos incrementando
         if (si.orden != 0)
         {
             si.orden = orden;
             orden++;
         }
      }
      listaColumnas.Sort(delegate(stringInt si1, stringInt si2) { return si1.orden.CompareTo(si2.orden); });

       // tenemos la matriz con el orden de las columnas, ahora vamos a trasladarlo al datatable
       foreach(stringInt si in listaColumnas)
          dtTable.Columns[si.Nombre].SetOrdinal(si.orden);


        return dtTable;
}

Upvotes: 2

JBrooks
JBrooks

Reputation: 10013

You can do the column sorting in the table itself:

dt.Columns["Col0"].SetOrdinal(0);
dt.Columns["Col1"].SetOrdinal(1);
dt.Columns["Col2"].SetOrdinal(2);

Upvotes: 5

Ariel Popovsky
Ariel Popovsky

Reputation: 4875

You don't need to sort the columns in the DataTable object, just copy the column names to an array and sort the array. Then use the array to access the column values in the right order.

Sample:

class Program
    {
        static void Main(string[] args)
        {
            var dt = new DataTable { Columns = { "A3", "A2", "B1", "B3", "B2", "A1" } };
            dt.BeginLoadData();
            dt.Rows.Add("A3val", "A2val", "B1val", "B3val", "B2val", "A1val");
            dt.EndLoadData();

            string[] names=new string[dt.Columns.Count];
            for (int i = 0; i < dt.Columns.Count;i++ )
            {
                names[i] = dt.Columns[i].ColumnName;
            }
            Array.Sort(names);

            foreach (var name in names)
            {
                Console.Out.WriteLine("{0}={1}", name, dt.Rows[0][name]);
            }
            Console.ReadLine();
        }

Upvotes: 4

Rubens Farias
Rubens Farias

Reputation: 57996

You'll probably need to implement your IComparer<T>, as "natural" order would be: Col0, Col1, Col3, Col43 and Col6. ("4" comes before "6")

Upvotes: 1

Related Questions