2013-05-28 40 views
1

我发现很多东西在删除重复重命名重复行,但我无法找到任何地方以下问题的任何指导......如何计算和数据表中的

我正在寻找一种方式来重命名我从CSV导入到的C#DataTable中的任何重复行。我的数据看起来类似:

**Name**  **Item**     **Quantity** 
ABC   Item_Name      6 
ABC   Item_Name_2     1 
DEF   Item_Name      3 
GHI   Item_Name_2     7 
ABC   Item_Name      6 
ABC   Item_Name      1 
JKL   Item_Name_3     4 
ABC   Item_Name      6 
ABC   Item_Name      1 
JKL   Item_Name_3     4 

我想什么数据的样子,如果一整行(包括数量)出现不止一次,是这样的:

**Name**   **Item**     **Quantity** 
ABC   Item_Name      6 
ABC   Item_Name_2      1 
DEF   Item_Name      3 
GHI   Item_Name_2      7 
ABC (2)  Item_Name      6 
ABC (2)  Item_Name_2      1 
JKL   Item_Name_3      4 
ABC (3)  Item_Name      6 
ABC (3)  Item_Name_2      1 
JKL (2)  Item_Name_3      4 

目前,我'm使用双循环“for循环”来确定表下的哪些行与当前行具有相同的数据并相应地重命名它们。显然,这样做有两个问题:

  1. 这是与大量行的表很慢,很明显

  2. 今后所有行的name列是“ABC”现在有一个名称列“ABC( 2)“,不管这是他们的第一次还是第98次(因为坦率地说,我的代码很糟糕)。

任何帮助人都可以提供极大的赞赏:)

回答

2
foreach(DataRow row in thisTable.Rows) 
    { 
     string name = row.Item[0].ToString(); 

     if(name[name.Length - 3] == '(' && name[name.Length - 1] == ')') 
      continue; 

     string item = row.Item[1].ToString(); 
     int quantity = Convert.ToInt32(row.Item[2]); 
     string expression = "Name = " + name + " and Item = " + item + " and Quantity = " + quantity; 

     DataRow[] matchingRows = table.Select(expression); 
     for(int i = 1; i < matchingRows.Length; i++) 
      matchingRows[i]["Name"] += " (" + i + ")"; 
    } 

基本上,我刚刚经历的每一行循环。然后,我查询每个相同的行。然后,我遍历这些相同的行,并用(1),(2),(3)等附加字符串(按查询发现它们的顺序)重命名它们。我也跳过任何我已经用'if'语句重命名的行(我假设重命名的行以“(”在最后一个字符的第三个字符和“)”结尾)。对不起,如果我在代码中犯了与C#语法相关的错误。虽然这个想法很简单。

+0

除了将更改提交给DataTable外,它正在做正确的事情。我无法将行导入或加载到表中,因为它与“foreach”中的“in”枚举冲突。有小费吗? – LeeCambl

+0

嗯。尝试matchingRows [i] [“Name”] + =“(”+ i +“)”or matchingRows [i] .SetField(“Name”,matchingRows [i] [“Name”] +“(”+ i + )“)。如果这不起作用,请尝试设置thisTable.Columns.readOnly = false。 –

+0

是...使用matchingRows [i] [“Name”]整理出来。有没有一个合理的解释,为什么要改变命名列的作品,并使更改ItemArray不? 这是我在这里问的第一个问题,我应该编辑您的答案以包含该更改,然后将其标记为解决方案?这通常是如何工作的? – LeeCambl

0

下面是一个不同的解决方案。在我看来,更优雅!

 DataTable table = new DataTable(); 
     table.Columns.Add("Name", typeof(string)); 
     table.Columns.Add("Title", typeof(string)); 
     table.Columns.Add("Quantity", typeof(int)); 

     // Data for test 
     table.Rows.Add("ABC", "Item_name", 6); 
     table.Rows.Add("ABC", "Item_name", 6); 
     table.Rows.Add("ABC2", "Item_name", 6); 
     table.Rows.Add("ABC2", "Item_name", 6); 
     table.Rows.Add("ABC2", "Item_name", 6); 
     table.Rows.Add("ABC2", "Item_name", 6); 

     // Query with Linq 
     var query = from row in table.AsEnumerable() 
        group row by new { 
         name = row.Field<String>("Name"), 
         title = row.Field<String>("Title") 
        } into GrpNameTitle 
        select new { 
         Name = GrpNameTitle.Key.name + " (" + GrpNameTitle.Count() + ")", 
         Title = GrpNameTitle.Key.title, 
         Quantity = GrpNameTitle.First().Field<int>("Quantity") 
        }; 


     foreach (var itm in query) 
     { 
      Console.WriteLine("{0}\t{1}", itm.Name, itm.Title); 
     } 

我有一个问题,当您筛选行“组的”你的两列(姓名和职务)将是没有意义的添加/计算第三列包含的数量是多少?例如:

abc item_name 2 
abc item_name 2 

给这样的结果:

abc(2) item_name 4 

最好的问候,

导师雷卡。

+0

不错的想法,但不是,那不是我想要实现的。我应该更清楚自己的最终目标。我只是想将这些数据行标记为合法的重复项,因为源CSV是最终用户可以下订单的一部分,所以我只想将这些行标记为同一类型订单的单独实例,没有输入错误。 – LeeCambl

+0

尽管感谢您的回答:-) – LeeCambl