【问题标题】:Sorting DataTable-columns对 DataTable 列进行排序
【发布时间】:2023-04-06 10:48:01
【问题描述】:

我有一个类似这样的数据表:

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

如您所见,Cols 未按编号排序。这就是我希望它在“魔法”之后的样子:

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

C# 中是否有用于此类事情的内置函数?如果没有,我该如何开始?

【问题讨论】:

  • +1 解决了我的类似问题

标签: c# sorting datatable


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您不需要对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();
            }
    

    【讨论】:

    • 好的,我知道你的意思,它会很好用,但它并不完全......“正版”......不过,谢谢你的建议。
    • 如果你想要更“真实”的东西,也许你可以在另一端工作。谁在生成数据表,为什么列没有排序?您可能无法控制该查询或进程,但您可以,然后在那里对列进行排序。
    • 问题是,我无法控制用户向数据表添加新列的顺序。所以,例如如果他添加了一个新列,该列应该位于两个已经存在的列之间,但作为最后一列添加,我必须比较每一列,直到它适合:-/
    • 不过,我还是喜欢这个主意。我会将排序内容添加到 string[] 的get-accessor,因此无需太多开销即可完成。好主意!
    • 当用户添加列并像 JBrooks 建议的那样设置序号时如何排序。假设您有列“A1”、“A4”并且用户添加了“A2”,您通过列名查找插入新列的位置并手动设置序号。您应该检查将序号设置为现有值时会发生什么,可能所有这些都自动重新编号,或者您可能必须手动增加以下列上的序号。
    【解决方案3】:

    这是我的代码,当然不是最好的解决方案,但可以。就我而言,我设置了一个固定列,它可以是“Nombre”或“Problem”,这始终是列顺序中的第一个。

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

    【讨论】:

      【解决方案4】:
      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);
      

      【讨论】:

        【解决方案5】:

        您可能需要实现您的IComparer&lt;T&gt;,因为“自然”顺序是:Col0、Col1、Col3、Col43 和 Col6。 (“4”在“6”之前)

        【讨论】:

          【解决方案6】:

          以下是上述答案的组合。使用 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。
          猜你喜欢
          • 1970-01-01
          • 2017-11-25
          • 1970-01-01
          • 1970-01-01
          • 2020-08-17
          • 1970-01-01
          • 2020-12-22
          • 2015-04-01
          • 1970-01-01
          相关资源
          最近更新 更多