c# - Enumerable.Zip 强制执行相同的长度

标签 c# linq

我发现自己经常需要使用 Enumerable.Zip(),但使用它可以确保两个 IEnumerable 具有相同的长度(或两者都是无限的) ).例如,如果一个可枚举到达终点但另一个没有到达终点,我希望它抛出。根据doc , Zip() 将在其中一个结束时立即停止枚举。

我最终总是需要像下面这样的东西。解决此问题的最“内置”/最优雅的方法是什么?

void Foo(IEnumerable<int> a, IEnumerable<int> b)
{
    // caching them. they are not huge or infinite in my scenario
    var a = a.ToList();
    var b = b.ToList();

    if (a.Count() != b.Count())
    {
        throw ...;
    }

    Enumerable.Zip(a, b, ...);
}

最佳答案

我可能会按照您想要的方式重新实现 Zip。这真的很简单——以下是从 MoreLINQ 中简单改编而来的。请注意,您需要给它起一个更好的名称...

public static IEnumerable<TResult> ZipForceEqual<TFirst, TSecond, TResult>(
    this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> resultSelector)
{
    if (first == null) throw new ArgumentNullException("first");
    if (second == null) throw new ArgumentNullException("second");
    if (resultSelector == null) throw new ArgumentNullException("resultSelector");

    return ZipForceEqualImpl(first, second, resultSelector);
}

static IEnumerable<TResult> ZipForceEqualImpl<TFirst, TSecond, TResult>(
    IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> resultSelector)
{
    using (var e1 = first.GetEnumerator())
    using (var e2 = second.GetEnumerator())
    {
        while (e1.MoveNext())
        {
            if (e2.MoveNext())
            {
                yield return resultSelector(e1.Current, e2.Current);
            }
            else
            {
                throw new InvalidOperationException("Sequences differed in length");
            }
        }
        if (e2.MoveNext())
        {
            throw new InvalidOperationException("Sequences differed in length");
        }
    }
}

关于c# - Enumerable.Zip 强制执行相同的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29040250/

相关文章:

c# - 使用 LINQ "everywhere"时的性能问题?

c# - C# 中的 Google 网站站长工具 API

c#:如何从 linq 查询中设置组合框值成员

c# - linq 案例陈述

c# - 为什么 .NET decimal.ToString(string) 从零舍入,显然与语言规范不一致?

c# - 如何直接在 .NET 代码中快速创建虚拟图像

C#: FileStream.Read() 不读取文件直到最后,但返回 0

c# - 以简单的方式替换嵌套的 foreach

c# - 使用 LINQ 进行 Orderby 和 thenby

c# - 我可以使用 LINQ 从现有列表创建新的对象列表吗