基于列值拆分数据表

本文关键字:数据表 拆分 于列值 | 更新日期: 2023-09-27 17:56:51

我有一个包含布尔(位)列的数据表。

  a         b
------    ------ 
  1         10
  0         20
  1         30
  0         20
  1         10 

我希望根据此值将其拆分为 2 个可独立排序的数据表(a 列)

我看了一下,发现了一个老问题:

根据列值将数据表拆分为 2 个或更多数据表

这给了这个:

List<DataTable> result = myDataTable.AsEnumerable()
        .GroupBy(row => row.Field<Boolean>("a"))
        .Select(g => g.CopyToDataTable())
        .ToList();

但结果不是我可以使用result[0]引用的数据表列表,并且像我预期的那样result[1]

当我点击result[1]时,我得到:

"指数超出范围。必须为非负数且小于大小 的集合。参数名称:索引"

我会添加一条评论来询问,但该线程已经超过 2 年了,恐怕我不会得到回复。

任何人都可以建议一种使用此代码或新鲜事物来实现我需要的方法吗?

基于列值拆分数据表

考虑到数据表dt包含包括两列在内的所有记录,您可以使用过滤条件创建两个DataView,例如

EnumerableRowCollection<DataRow> query =
    from data in dt.AsEnumerable()
    where data.Field<bool>("a") == true 
    select data;
DataView view1 = query.AsDataView();

EnumerableRowCollection<DataRow> query1 =
    from data in dt.AsEnumerable()
    where data.Field<bool>("a") == false 
    select data;
DataView view2 = query1.AsDataView();

您的结果List<DataTable>。所以第一个表是result[0]的,第二个表是result[1]的。它永远不会包含两个以上的表。

它可以包含

  • 如果源表为空,则为 0 个表
  • 1 个表,
  • 如果所有表具有相同的值或
  • 如果两个值都包含,则为 2 个表。

从您的评论中:

当我尝试访问结果[0]时,我得到预期的缩短列表 结果。当我点击结果 [1] 时,我得到"索引超出范围。必须是 非负数且小于集合的大小。参数名称: 索引"

如果列表仅包含一个表,则会出现该异常,并且仅当行具有所有相同的列值(即所有行都有 1)时才

会出现这种情况。

但是,如果需要,可以使用另一种方法。这使用Lookup<TKey, TValue>

var aColLookup= myDataTable.AsEnumerable().ToLookup(row => row.Field<int>("a"));
DataTable trueTable = myDataTable.Clone();
DataTable falseTable = myDataTable.Clone();
if(aColLookup[1].Any())
    trueTable = aColLookup[1].CopyToDataTable();
if (aColLookup[0].Any())
    falseTable = aColLookup[0].CopyToDataTable();

我必须使用Clone(创建一个具有相同列的空表)和Any -check,因为如果序列不包含行CopyToDataTable会引发异常。

 Globals.Productsdt = Pfdt.AsEnumerable()
                                            .Where(r => r.Field<string>("basecurve") == PFlist[j].PFBC.ToString())
                                            .Where(r => r.Field<string>("diameter") == PFlist[j].PFDM.ToString())
                                            .CopyToDataTable();