使用IEqualityComparer for Union
我只是想从两个列表中删除重复项并将它们组合成一个列表。 我还需要能够定义什么是重复的。 我通过ColumnIndex属性定义了一个重复项,如果它们相同,它们是重复的。 这是我采取的方法:
我发现了一个很好的例子,说明如何为随机事件编写内联比较器,而在代码段中只需要em一次。
public class InlineComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> getEquals;
private readonly Func<T, int> getHashCode;
public InlineComparer(Func<T, T, bool> equals, Func<T, int> 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<Issue>((i1, i2) => i1.ColumnInfo.ColumnIndex == i2.ColumnInfo.ColumnIndex,
i => i.ColumnInfo.ColumnIndex);
var filteredIssues = groupIssues.Union(formatIssues, dupComparer);
但结果集为空。
我在哪里误入歧途? 我已经确认这两个列表的列具有相同的ColumnIndex属性。
我刚刚在一个测试集上运行你的代码....它的工作原理!
public class InlineComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> getEquals;
private readonly Func<T, int> getHashCode;
public InlineComparer(Func<T, T, bool> equals, Func<T, int> 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<TestClass>()
{
new TestClass() {S = "one"},
new TestClass() {S = "two"},
};
var l2 = new List<TestClass>()
{
new TestClass() {S = "three"},
new TestClass() {S = "two"},
};
var dupComparer = new InlineComparer<TestClass>((i1, i2) => i1.S == i2.S, i => i.S.GetHashCode());
var unionList = l1.Union(l2, dupComparer);
Assert.AreEqual(3, unionList);
}
所以...也许回去检查一下你的测试数据 - 或者用其他一些测试数据运行它?
毕竟 - 联盟是空的 - 这表明你的输入列表也是空的?
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<Issue> {i})
.Any(x => x.ColumnIndex == i.ColumnIndex));
var filteredIssues = formatIssues.Union(groupIssues).Except(dupeIssues);
一个稍微简单的方法 - 是的,它确实保留了原来的命令,消除了第二次和以后的愚蠢。
formatIssues.Union(groupIssues).DistinctBy(x => x.ColumnIndex)
这是MoreLinq
的DistinctBy
lambda方法
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> knownKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (knownKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
链接地址: http://www.djcxy.com/p/85325.html