3
    [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 吗?我认为这仅对复杂类型是必需的。

4

2 回答 2

7

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,因此它会多次返回相同的项目。

于 2012-09-12T15:06:46.207 回答
0

除了返回一组值,这意味着它将只返回每个值一次

于 2012-09-12T15:08:00.433 回答