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

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

  1. 显然,具有大量行的表真的很慢

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

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

4

2 回答 2

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 个到最后一个字符处以“(”结尾,在最后一个字符处以“)”结尾)。抱歉,如果我在代码中犯了与 C# 语法相关的错误。不过,这个想法非常简单。

于 2013-05-28T14:34:15.827 回答
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

此致,

导师雷卡。

于 2013-05-28T15:01:21.897 回答