如何计算和重命名DataTable中的重复行

时间:2013-05-28 13:47:52

标签: c# datatable duplicates datarow

我发现有很多东西要删除重复项,但我无法在任何地方找到任何问题的指导......

我正在寻找一种方法来重命名我从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

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

  1. 对于包含大量行的表格来说,这显然很慢,显然

  2. 名称列为“ABC”的所有未来行现在都有一个名称列“ABC(2)”,无论这是第一次出现还是出现第98次(因为,坦率地说,我的代码很糟糕) 。

  3. 任何人都可以提供任何帮助,非常感谢:)

2 个答案:

答案 0 :(得分: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'语句重命名的任何行(我假设一个重命名的行以“(”在第3个到最后一个char和“)结束”)在最后一个字符处。很抱歉,如果我在代码中发生了与C#-syntax相关的错误。不过,这个想法很简单。

答案 1 :(得分: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

致以最诚挚的问候,

Mentor Reka。

相关问题