You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于指定列对DataTable去重遇问题:现有代码无返回值求协助

问题分析

你原代码的逻辑完全错误:DistinctBy的key是判断表列集合是否包含拼接后的列名字符串,得到的是布尔值。如果所有行的这个判断结果一致,最终只会留一行;若判断结果为false则返回空数组,这和按指定列去重的需求完全不符。

解决方案

推荐三种可行的实现方式,按推荐程度排序:

1. 使用DataView原生去重(最简洁高效)

DataTable原生提供了通过DataView.ToTable实现按指定列去重的方法,无需手动处理比较逻辑:

// 创建DataView
DataView dataView = new DataView(dataTable1);
// 调用ToTable,第一个参数true表示去重,第二个参数传入要去重的列名数组
DataTable distinctTable = dataView.ToTable(true, columnsToBeUnique);
// 转换为DataRow数组
var result = distinctTable.AsEnumerable().ToArray();

2. 自定义数组比较器配合DistinctBy

如果需要用Linq的方式实现,可以通过自定义数组比较器,将指定列的值数组作为去重依据:
首先实现数组比较器(用于正确比较值数组的内容):

public class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
    public bool Equals(T[] x, T[] y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        if (x.Length != y.Length) return false;
        
        for (int i = 0; i < x.Length; i++)
        {
            if (!EqualityComparer<T>.Default.Equals(x[i], y[i]))
                return false;
        }
        return true;
    }

    public int GetHashCode(T[] obj)
    {
        if (obj == null) return 0;
        int hash = 17;
        foreach (var item in obj)
        {
            hash = hash * 31 + (item?.GetHashCode() ?? 0);
        }
        return hash;
    }
}

然后使用Linq去重:

var result = dataTable1
    .AsEnumerable()
    .DistinctBy(row => columnsToBeUnique.Select(col => row[col]).ToArray(), new ArrayEqualityComparer<object>())
    .ToArray();

3. 序列化列值为字符串(简单但性能一般)

如果数据量不大,可以将指定列的值序列化为唯一字符串作为去重键,利用JSON序列化即可:

using System.Text.Json;

var result = dataTable1
    .AsEnumerable()
    .DistinctBy(row => JsonSerializer.Serialize(columnsToBeUnique.Select(col => row[col])))
    .ToArray();

注意:若列值中包含特殊字符,序列化能保证键的唯一性,但大数据量下性能不如前两种方法。

内容的提问来源于stack exchange,提问作者Rico Strydom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:55:07