[TestMethod()]
public void TestExceptWithRandomInput()
{
byte[] listA = new byte[4096];
var rand = new Random();
rand.NextBytes(listA);
byte[] listB = new byte[] { 0x00 };
var nullCount = (from a in listA
where a == 0x00
select a);
var listC = listA.Except(listB);
Assert.AreEqual(4096, listA.Length);
Assert.AreEqual(4096 - nullCount.Count(), listC.Count()); //Fails!!
}
[TestMethod()]
public void TestWhereWithRandomInput()
{
byte[] listA = new byte[4096];
var rand = new Random();
rand.NextBytes(listA);
byte[] listB = new byte[] { 0x00 };
var nullCount = (from a in listA
where a == 0x00
select a);
var listC = listA.Where(a => !listB.Contains(a));
Assert.AreEqual(4096, listA.Length);
Assert.AreEqual(4096 - nullCount.Count(), listC.Count()); //Successful
}
上面的代码似乎在使用 Except() 函数时失败,但在使用 Where() 时工作正常。好像少了什么?我需要为字节实现 IEqualityComparer 吗?我认为这只是复杂类型所必需的。
最佳答案
Except
也去除了第一个参数中的重复项。这是一个集合操作,集合并不意味着有重复 - 与 Union
、Intersect
等相同。
listA.Except(listB)
给出 listA
中的所有唯一、非空字节。
如果您想获取序列中的所有非空字节,listA.Where(b => b != 0x00)
可能是合乎逻辑的做法。
如果你想计算空字节,listA.Count(b => b == 0x00)
表达得最清楚。
如果你想要一个“除了但保留重复项”,而不是对每个不是很有效的项目执行 !Contains
,你可以这样做:
public static IEnumerable<T> ExceptWithDuplicates<T>(
this IEnumerable<T> source1,
IEnumerable<T> source2)
{
HashSet<T> in2 = new HashSet<T>(source2);
foreach(T s1 in source1)
{
if(!in2.Contains(s1)) // rather than if Add
{
yield return s1;
}
}
}
(免责声明:不是用 IDE 编写的。)这与常规 Except
基本相同,但它不会添加源项到内部 HashSet
,所以它会多次返回相同的项目。
关于c# - Linq 的 except 方法不适用于字节值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12391107/