C#如何移除列表中数字组合相同仅顺序不同的重复元素
问题描述
现有初始化如下的字符串类型List:
List<string> MyList = new List<string>(); MyList.Add("153"); MyList.Add("112"); MyList.Add("531"); MyList.Add("675"); MyList.Add("889"); MyList.Add("351");
需求为:移除所有字符组成完全一致、仅字符排列顺序不同的等价元素,同组元素仅保留首次出现的那一个,最终预期输出结果为:
153 112 675 889
普通无参
Distinct()方法仅能匹配值完全相等的重复项,无法识别这类字符顺序不同的等价重复;已知可通过"153".OrderBy(i => i).SequenceEqual("531".OrderBy(i => i))判断两个字符串是否属于同组等价项,但不清楚如何基于该逻辑完成全列表去重。
实现方案
核心逻辑是为每个字符串生成统一的特征标识:将字符串的字符按固定规则排序后生成新串,两个字符串如果排序后的特征串完全一致,就判定为重复项。以下提供两种可直接运行的实现方式:
方式1:自定义相等比较器(可复用)
实现IEqualityComparer<string>接口,将排序判断逻辑封装到比较器中,可直接传入Distinct()方法使用,适合多处需要同类去重逻辑的场景:
// 自定义字符串等价比较器 public class CharSetSameComparer : IEqualityComparer<string> { public bool Equals(string x, string y) { // 空值边界处理 if (x == null || y == null) return x == y; // 长度不同直接判定不等,提前返回减少不必要计算 if (x.Length != y.Length) return false; // 字符排序后判断序列是否一致 return x.OrderBy(c => c).SequenceEqual(y.OrderBy(c => c)); } public int GetHashCode(string obj) { if (obj == null) return 0; // 生成排序后特征串的哈希码,保证等价字符串返回相同哈希值 return new string(obj.OrderBy(c => c).ToArray()).GetHashCode(); } }
调用方式:
var distinctResult = MyList.Distinct(new CharSetSameComparer()).ToList();
方式2:GroupBy分组(轻量一次性使用)
如果仅需要单次处理,不需要单独定义比较器类,可以直接按排序后的特征串分组,每组取第一个元素即可得到去重结果:
var distinctResult = MyList .GroupBy(str => new string(str.OrderBy(c => c).ToArray())) .Select(group => group.First()) .ToList();
两种方式执行后得到的结果完全匹配预期输出,且默认保留每组中第一个出现的原始元素。
内容的提问来源于stack exchange,提问作者James DEV
相关产品推荐
相关产品推荐

