DataTable列的排序

3

我有一个数据表格,类似于这样:

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

正如您所见,Col没有按其数字排序。这就是我希望在“魔法”之后它看起来的样子:

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

有没有C#内置的函数可以做到这样的事情?如果没有,我该如何开始呢?

1
+1 解决了我类似的问题。 - undefined
6个回答

5

您可以在表格本身中进行列排序:

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

4

您不需要对DataTable对象中的列进行排序,只需将列名复制到一个数组中并对该数组进行排序。然后使用该数组按正确顺序访问列值。

示例:

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();
        }

好的,我知道你的意思,而且它会很有效,但是它不太... "真实"... 不过,还是谢谢你的建议。 - undefined
如果你想要更加“真实”的东西,或许你可以从另一端着手。是谁在生成数据表?为什么列没有按顺序排列?也许你无法控制查询或者处理过程,但如果可以的话,在那里对列进行排序。 - undefined
问题是,我无法控制用户向数据表中添加新列的顺序。例如,如果他添加了一个应该位于两个已存在列之间的新列,但却被添加为最后一列,那么我就必须逐个比较每一列,直到找到合适的位置 :-/ - undefined
不过,我喜欢这个想法。我会将排序功能添加到字符串数组的“get”访问器中,这样就不会增加太多额外的开销。好主意! - undefined
当用户添加列并设置顺序时,排序如何处理?就像JBrooks建议的那样。假设你有“A1”,“A4”两列,然后用户添加了“A2”,你需要遍历列名来寻找插入新列的位置,并手动设置顺序。你应该检查当你将顺序设置为已存在的值时会发生什么,也许它们会自动重新编号,或者你需要手动增加后续列的顺序值。 - undefined

2
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);

2

以下是我的代码,虽然不是最佳解决方案,但可行。在我的情况下,我设置了一个固定列,可以是“名称”或“问题”,这始终是列顺序中的第一列。

// 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;
}

1

你可能需要实现你的 IComparer<T>,因为“自然”顺序应该是:Col0、Col1、Col3、Col43 和 Col6。("4" 在 "6" 之前)


-1
这是前面答案的结合。使用List或字符串数组的内置Sort()方法对列名列表进行排序,然后使用DataColumn.SetOrdinal()方法重新排列DataTable的列以匹配排序后的列表。
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++;
}

(“table”是你的DataTable的名称。)

同意,如果人们要投票反对,他们至少应该有礼貌地解释原因。一个原因可能是,排序会按字母顺序进行排序,但如果你有Col1、Col2和Col11,你会发现结果的排序将是Col1、Col11、Col2。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接