Reputation: 17831
I have a datatable something like this:
| Col1 | Col6 | Col3 | Col43 | Col0 |
---------------------------------------------------
RowA | 1 | 6 | 54 | 4 | 123 |
As you see, the Col
s 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
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
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
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
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
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
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