使用IEqualityComparer for Union

我只是想从两个列表中删除重复项并将它们组合成一个列表。 我还需要能够定义重复的内容。 我通过ColumnIndex属性定义副本,如果它们相同,则它们是重复的。 这是我采取的方法:

我找到了一个很好的例子,说明如何为代码段中只需要一次的随机场所编写内联比较器。

public class InlineComparer : IEqualityComparer { private readonly Func getEquals; private readonly Func getHashCode; public InlineComparer(Func equals, Func hashCode) { getEquals = equals; getHashCode = hashCode; } public bool Equals(T x, T y) { return getEquals(x, y); } public int GetHashCode(T obj) { return getHashCode(obj); } } 

然后我只有两个列表,并尝试使用比较器对它们进行联合。

  var formatIssues = issues.Where(i => i.IsFormatError == true); var groupIssues = issues.Where(i => i.IsGroupError == true); var dupComparer = new InlineComparer((i1, i2) => i1.ColumnInfo.ColumnIndex == i2.ColumnInfo.ColumnIndex, i => i.ColumnInfo.ColumnIndex); var filteredIssues = groupIssues.Union(formatIssues, dupComparer); 

但结果集为空。

我哪里误入歧途? 我已经确认这两个列表具有相等ColumnIndex属性的列。

我只是在测试集上运行你的代码….它的工作原理!

  public class InlineComparer : IEqualityComparer { private readonly Func getEquals; private readonly Func getHashCode; public InlineComparer(Func equals, Func hashCode) { getEquals = equals; getHashCode = hashCode; } public bool Equals(T x, T y) { return getEquals(x, y); } public int GetHashCode(T obj) { return getHashCode(obj); } } class TestClass { public string S { get; set; } } [TestMethod] public void testThis() { var l1 = new List() { new TestClass() {S = "one"}, new TestClass() {S = "two"}, }; var l2 = new List() { new TestClass() {S = "three"}, new TestClass() {S = "two"}, }; var dupComparer = new InlineComparer((i1, i2) => i1.S == i2.S, i => iSGetHashCode()); var unionList = l1.Union(l2, dupComparer); Assert.AreEqual(3, unionList); } 

那么……也许回去查看你的测试数据 – 或者用其他一些测试数据运行它?

毕竟 – 对于一个联盟是空的 – 这表明你的输入列表也都是空的?

一种稍微简单的方式 – 是的,它确实保留了删除第二次和随后的欺骗的原始顺序。

 formatIssues.Union(groupIssues).DistinctBy(x => x.ColumnIndex) 

这是MoreLinqDistinctBy lambda方法

 public static IEnumerable DistinctBy (this IEnumerable source, Func keySelector) { HashSet knownKeys = new HashSet(); foreach (TSource element in source) { if (knownKeys.Add(keySelector(element))) { yield return element; } } } 

Linq Except方法不适合你吗?

 var formatIssues = issues.Where(i => i.IsFormatError == true); var groupIssues = issues.Where(i => i.IsGroupError == true); var dupeIssues = issues.Where(i => issues.Except(new List {i}) .Any(x => x.ColumnIndex == i.ColumnIndex)); var filteredIssues = formatIssues.Union(groupIssues).Except(dupeIssues);