【问题标题】:Delete row from datatable where first column does not contain (some string)从数据表中删除第一列不包含的行(某些字符串)
【发布时间】:2012-02-18 16:54:49
【问题描述】:

我有包含以下列的 DataTable:

ClientID date numberOfTransactions price

ClientID 是字符串类型,我需要确保它的内容对于表中的每个值都包含“A-”和“N6”。

我需要从 DataTable 中删除所有行,其中第一列 (ClientID) 不包含“A-”“N6”(一些总计和其他不必要的数据)。如何从 DataTable 中专门选择和删除这些行?

我知道:

foreach (DataRow row in table.Rows) // Loop over the rows.
    {

        //Here should come part "if first column contains mentioned values
    }

这个我也知道

If (string.Contains("A-") == true &&  string.Contains("N6") == true)

{
//Do something
}

我需要帮助如何为每行的第一列实现此功能。

【问题讨论】:

  • 你试过什么查询..?还有你使用 SQL Server、MYSQL 等什么数据库?
  • 这个问题太模糊了;给我们更多的细节,请
  • 我相信 OP 只是想从 DataTable.Rows 集合中删除某些 DataRows(在内存中),因此知道数据来自哪里实际上可能无关紧要(因此他/她感到困惑)。

标签: c# datatable


【解决方案1】:

这应该更有效,无论是代码行还是时间,试试这个:)

for(int x=0; x<table.Rows.Count;)
{
   if (!table.Rows[x].ItemArray[0].contains("A-") && !table.Rows[x].ItemArray[0].contains("N6"))
      table.Rows.RemoveAt(x);
   else x++;
}

快乐编码

【讨论】:

    【解决方案2】:

    试试这个,

    假设 dt 作为您的 Datatabe 对象,ClientID 作为您的第一列(因此使用 ItemArray[0])

    for(int i=0; i<dt.Rows.Count; i++)
    {
      temp = dt.Rows[i].ItemArray[0].ToString();
    
    if (System.Text.RegularExpressions.Regex.IsMatch(temp, "A-", System.Text.RegularExpressions.RegexOptions.IgnoreCase) || System.Text.RegularExpressions.Regex.IsMatch(temp, "N6", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
       {
         dt.Rows.RemoveAt(i);
         i--;
       }
     }
    

    简单直接的解决方案...希望对您有所帮助

    【讨论】:

    • 如果你这样做,你不会冒着在迭代过程中跳过行的风险吗?假设 i = 2 并且您找到需要删除的行。您删除了调整所有其他行索引的行 (2) - 但现在 i = 3,所以 new (2) 没有得到评估,对吧?
    • 同意,在迭代时从集合中删除会导致问题。
    • @C.Barlow,你是对的。我的错。忘了再添加一行:“i--;”就是这样。
    • 我遇到了同样的问题,找到了这个答案,就像一个魅力:)
    【解决方案3】:

    前言:C.Barlow's existing answer 太棒了,这只是人们可以采取的另一条路线。

    这是一种无需遍历原始表的方法(利用DataTable.Select() 方法):

    DataTable table = new DataTable(); // This would be your existing DataTable
    // Grab only the rows that meet your criteria using the .Select() method
    DataRow[] newRows = table.Select("ClientID LIKE '%A-%' AND ClientID LIKE '%N6%'");
    // Create a new table with the same schema as your existing one.
    DataTable newTable = table.Clone();
    foreach (DataRow r in newRows)
    {
        // Dump the selected rows into the table.
        newTable.LoadDataRow(r.ItemArray, true);
    }
    

    现在您有一个DataTable,其中只有您想要的行。如有必要,此时您可以清除原始表格并将其替换为新表格的内容:

    table.Clear();
    table = newTable.Copy();
    


    编辑:昨晚我想到了内存优化,一旦你有你需要的行,你就可以覆盖现有的表,这样就不需要临时表了。
    DataTable table = new DataTable(); // This would be your existing DataTable
    // Grab only the rows that meet your criteria using the .Select() method
    DataRow[] newRows = table.Select("ClientID LIKE '%A-%' AND ClientID LIKE '%N6%'");
    // Clear out the old table
    table.Clear();
    foreach (DataRow r in newRows)
    {
        // Dump the selected rows into the table.
        table.LoadDataRow(r.ItemArray, true);
    }
    

    【讨论】:

    • 不错! +1 提高效率并且通常很时髦!
    【解决方案4】:

    试试这个:

    编辑:最后一行完全搞砸了,所以如果你试过了,现在就试试吧,因为我让它不傻了。 =)

    List<int> IndicesToRemove = new List<int>();
    DataTable table = new DataTable(); //Obviously, your table will already exist at this point
    foreach (DataRow row in table.Rows)
    {
       if (!(row["ClientID"].ToString().Contains("A-") && row["ClientID"].ToString().Contains("N6")))
          IndicesToRemove.Add(table.Rows.IndexOf(row));
    }
    IndicesToRemove.Sort();
    for (int i = IndicesToRemove.Count - 1; i >= 0; i--) table.Rows.RemoveAt(IndicesToRemove[i]);
    

    【讨论】:

    • 太棒了!非常感谢!
    猜你喜欢
    • 2020-09-11
    • 2021-04-28
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2020-03-25
    • 2019-09-14
    • 2020-03-19
    • 1970-01-01
    相关资源
    最近更新 更多