【问题标题】:Delete duplicate rows from datatable based on 2 columns in c#根据c#中的2列从数据表中删除重复的行
【发布时间】:2021-06-25 15:33:49
【问题描述】:

如何从存在相同名称和部门组合组合的数据表中删除重复行?我需要保留一个条目。

DataTable dt = new DataTable();
dt.Columns.Add("id");
dt.Columns.Add("Name");
dt.Columns.Add("Dept");

dt.Rows.Add(1, "Test1", "Sample1");
dt.Rows.Add(2, "Test2", "Sample2");
dt.Rows.Add(3, "Test3", "Sample3");
dt.Rows.Add(4, "Test4", "Sample4");  // Duplicate 
dt.Rows.Add(5, "Test4", "Sample4");  // Duplicate 
dt.Rows.Add(6, "Test4", "Sample4");  // Duplicate 
dt.Rows.Add(7, "Test4", "Sample5");  

结果数据表应该是,

dt.Rows.Add(1, "Test1", "Sample1");
dt.Rows.Add(2, "Test2", "Sample2");
dt.Rows.Add(3, "Test3", "Sample3");
dt.Rows.Add(4, "Test4", "Sample4");  
dt.Rows.Add(6, "Test4", "Sample5");  

如何在 c# 中做到这一点

【问题讨论】:

  • 一种“愚蠢”的算法是遍历每一行,创建一个副本,如果尚未存储,则将其存储在列表中。在存储之前进行比较。您的列表将没有重复项。表越大,这个算法就会越慢。
  • 我想这个问题的答案可能就是你所需要的:stackoverflow.com/questions/3242892/…

标签: c# linq


【解决方案1】:

简单

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Dept", typeof(string));

            dt.Rows.Add(1, "Test1", "Sample1");
            dt.Rows.Add(2, "Test2", "Sample2");
            dt.Rows.Add(3, "Test3", "Sample3");
            dt.Rows.Add(4, "Test4", "Sample4");  // Duplicate 
            dt.Rows.Add(5, "Test4", "Sample4");  // Duplicate 
            dt.Rows.Add(6, "Test4", "Sample4");  // Duplicate 
            dt.Rows.Add(7, "Test4", "Sample5");

            DataTable dt2 = dt.AsEnumerable()
                .OrderBy(x => x.Field<int>("id"))
                .GroupBy(x => new { name = x.Field<string>("Name"), dept = x.Field<string>("Dept") })
                .Select(x => x.First())
                .CopyToDataTable();

        }
    }
}

【讨论】:

  • 我正在使用没有 AsEnumerable() 扩展的 .net 核心
  • 2018 年 10 月(核心 3.0 之前)的以下文章说核心具有 linq。您是否尝试在模块顶部放置“使用 System.Linq”? docs.microsoft.com/en-us/dotnet/csharp/tutorials/…
  • 添加 System.Data.DataSetExtensions nuget 包有帮助
  • 优秀的解决方案,谢谢!
【解决方案2】:

这是我从某人那里得到的一个函数:

用法:

List<string> columnName = new List<string> { "ID", "coulmn1", "coulmn_2", "Another", "however_many_columns_you_want_really" };
dataGrid = RemoveDuplicatesFromDataTable(dataGrid, columnName);

功能:

static DataTable RemoveDuplicatesFromDataTable(DataTable table, List<string> keyColumns)
{
    Dictionary<string, string> uniquenessDict = new Dictionary<string, string>(table.Rows.Count);
    StringBuilder stringBuilder = null;
    int rowIndex = 0;
    DataRow row;
    DataRowCollection rows = table.Rows;
    while (rowIndex < rows.Count - 1)
    {
        row = rows[rowIndex];
        stringBuilder = new StringBuilder();
        foreach (string colname in keyColumns)
        {
            //stringBuilder.Append(((double)row[colname]));
            stringBuilder.Append(row[colname]);
        }
        if (uniquenessDict.ContainsKey(stringBuilder.ToString()))
        {
            rows.Remove(row);
        }
        else
        {
            uniquenessDict.Add(stringBuilder.ToString(), string.Empty);
            rowIndex++;
        }
    }

    return table;
}

【讨论】:

  • 很好的解决方案,我只加了两分钱。 while (rowIndex &lt; rows.Count - 1) 将在 DT 中返回 2 行具有相同值的行,而如果您只想有一个(唯一)行,正确的代码是 while (rowIndex &lt; rows.Count )
猜你喜欢
  • 2018-05-30
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 2021-06-24
  • 2020-11-24
  • 1970-01-01
  • 2014-05-09
  • 2021-12-06
相关资源
最近更新 更多