我发现自己经常需要使用Enumerable.Zip()
,但要确保两个IEnumerable
s具有相同的长度(或两者都是无限的).例如,如果一个可枚举到达终点但另一个没有,我希望它抛出.根据文档,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, ...);
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 14
我可能只是重新实现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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
867 次 |
最近记录: |