LINQ 压缩所有元素

bud*_*udi 4 c# linq

有没有办法利用Enumerable.Zip,其中IEnumerable使用了两个s 中的所有元素?如果IEnumerables 有不同的计数,则默认剩余合并为default(T)


例子

var first = new int[] { 1, 2, 3, 4, 5 };
var second = new string[] { "a", "b", "c" };
var zipped = first.Zip(second, (f, s) => new { f, s });
// actual:    [ {1, "a"}, {2, "b"}, {3, "c"} ]
// expecting: [ {1, "a"}, {2, "b"}, {3, "c"}, {4, null}, {5, null} ]

var first = new int[] { 1, 2, 3 };
var second = new string[] { "a", "b", "c", "d", "e" };
var zipped = first.Zip(second, (f, s) => new { f, s });
// actual:    [ {1, "a"}, {2, "b"}, {3, "c"} ]
// expecting: [ {1, "a"}, {2, "b"}, {3, "c"}, {0, "d"}, {0, "e"} ]
Run Code Online (Sandbox Code Playgroud)

oct*_*ccl 5

那么你可以创建你的自定义Zip扩展方法:

static IEnumerable<T> Zip<T1, T2, T>(this IEnumerable<T1> first,
                                    IEnumerable<T2> second, Func<T1, T2, T> operation)
{
    using (var iter1 = first.GetEnumerator())
    using (var iter2 = second.GetEnumerator())
    {
        while (iter1.MoveNext())
        {
            if (iter2.MoveNext())
            {
                yield return operation(iter1.Current, iter2.Current);
            }
            else
            {
                yield return operation(iter1.Current, default(T2));
            }
        }
        while (iter2.MoveNext())
        {
            yield return operation(default(T1), iter2.Current);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

主要思想来自this post answer。如果需要,您可以在dotnetfiddle对其进行测试


小智 5

尝试 MoreLinq 的ZipLongest方法:

如果两个输入序列的长度不同,则结果序列将始终与两个输入序列中较长的一个一样长。较短序列元素类型的默认值用于填充。该运算符使用延迟执行并流式传输其结果。