问题描述
在 Linq 中,我们可以将两个列表与 Enumerable.Zip 方法:
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>( this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector )
我希望将任意数量的相同类型的枚举等同于 Zip.带有方法签名的东西有点像这样:
public static IEnumerable<TResult> Zip<TIn, TResult>(IEnumerable<IEnumerable<TIn>>inputs, Func<IEnumerable<TIn>, TResult> combiner)
当迭代可枚举时,它返回一个可枚举,其中包含来自每个对应可枚举的元素.
这在任何地方都存在吗?或者使用现有的 Linq 方法构建是否简单?聚合多个 zip?
推荐答案
由于输入是一个数组,所以可以创建一个IEnumerator<TIn>[]然后对它们中的每一个调用 MoveNext.像这样的:
IEnumerator<T>[] enumerators = inputs.Select(inp => inp.GetEnumerator()).ToArray(); int len = enumerators.Length; while (true) { TResult[] result = new TResult[len]; for(int i = 0; i < len; ++i) { if (!enumerators[i].MoveNext()) yield break; result[i] = resultSelector(enumerators[i].Current); } yield return result; }
问题描述
In Linq we can combine two lists with a the Enumerable.Zip method:
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>( this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector )
I would like the equivalent to Zip an arbitrary number of enumerables of the same type. Something with a method signature a bit like this:
public static IEnumerable<TResult> Zip<TIn, TResult>(IEnumerable<IEnumerable<TIn>>inputs, Func<IEnumerable<TIn>, TResult> combiner)
Where the as the enumerable is iterated, it returns an enumerable containing an element from each of the corresponding enumerables.
Does this exist anywhere? Or is it simple to build with existing Linq methods? Aggregate multiple zips?
推荐答案
Since the input is an array, you can create an IEnumerator<TIn>[] Then call MoveNext on each of them. Something like this:
IEnumerator<T>[] enumerators = inputs.Select(inp => inp.GetEnumerator()).ToArray(); int len = enumerators.Length; while (true) { TResult[] result = new TResult[len]; for(int i = 0; i < len; ++i) { if (!enumerators[i].MoveNext()) yield break; result[i] = resultSelector(enumerators[i].Current); } yield return result; }