除外比较调用(第一个)集合中的项
本文关键字:集合 第一个 比较 调用 | 更新日期: 2023-09-27 18:27:37
我正在使用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中删除所有项。如何避免额外的比较?
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();
如果您也想查看重复项,可以使用Except:的此变体
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