我正在使用Enumerable.Except()从 activatedSerialNumbers 中排除 skipSerialNumbers 项目。
activatedSerialNumbers = activatedSerialNumbers
.Except(skipSerialNumbers, new SamWithLicenseComparer()).ToList();
SamWithLicenseComparer 是:
internal class SamWithLicenseComparer : IEqualityComparer<SamWithLicense>
{
public bool Equals(SamWithLicense x, SamWithLicense y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
return false;
if(x.Name.ToLower() != y.Name.ToLower())
return false;
return true;
}
public int GetHashCode(SamWithLicense sam)
{
if (ReferenceEquals(sam, null))
return 0;
return sam.Name == null ? 0 : sam.Name.ToLower().GetHashCode();
}
}
因此,我得到了意想不到的价值,因为正如我发现的那样, activatedSerialNumbers 中的项目与自己进行比较。但逻辑是它们可能具有相同的名称,任务只是从 skipSerialNumbers 中删除所有项目。怎么做才能避免额外的比较?
答案 0 :(得分:3)
Except
是一个集合操作,因此结果将始终包含不同的值
例如,如果您执行{A,B,A,C}.Except({B,C})
,则会获得{A}
,而不是{A, A}
。
你可以试试这个:
var skipSesialNumbersSet = new HashSet<SamWithLicense>(skipSerialNumbers, new SamWithLicenseComparer());
activatedSerialNumbers = activatedSerialNumbers.Where(x => !skipSesialNumbersSet.Contains(x)).ToList();
答案 1 :(得分:0)
如果您还想查看重复项,可以使用以下的变体:
public static IEnumerable<TSource> ExceptWithDuplicates<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second)
{
if (first == null) { throw new ArgumentNullException("first"); }
if (second == null) { throw new ArgumentNullException("second"); }
var secondList = second.ToList();
return first.Where(s => !secondList.Remove(s));
}
public static IEnumerable<TSource> ExceptWithDuplicates<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second,
IEqualityComparer<TSource> comparer)
{
if (first == null) { throw new ArgumentNullException("first"); }
if (second == null) { throw new ArgumentNullException("second"); }
var comparerUsed = comparer ?? EqualityComparer<TSource>.Default;
var secondList = second.ToList();
foreach (var item in first)
{
if (secondList.Contains(item, comparerUsed))
{
secondList.Remove(item);
}
else
{
yield return item;
}
}
}
现在你可以这样做:
var first = new [] { 1, 1, 1, 2, 2, 2, 3, 3 };
var second = new[] { 1, 2, 2, 4 };
var withoutDuplicates = first.Except(second); // 3
var witDuplicates = first.ExceptWithDuplicates(second); // 1, 1, 2, 3, 3 : Note that 1 and 2 are also in the list