c#中是否已存在条件性Zip功能?

Ada*_*lls 12 c# linq ienumerable linq-to-objects system.reactive

C#中是否已经有一个可以执行"条件性压缩"的功能?

是否有一个函数允许不同的长度输入并采用一个谓词来确定何时递增较小的源枚举器,以便可以看到较大源中的所有元素?

作为一个人为的例子,假设我们有一个可枚举的素数和一个可枚举的整数(都是按升序排序).我们希望生成一个新的枚举,它包含自上一个素数以来的素数和所有整数.

{2, 3, 5, 7, 11}

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10,}

{2, [1]}, {3,[]}, {5, [4]}, {7, [6]}, {11, [8,9,10]}
Run Code Online (Sandbox Code Playgroud)

max*_*max 5

我的解决方案:

public static IEnumerable<Tuple<T1, IEnumerable<T2>>> ConditionalZip<T1, T2>(
    this IEnumerable<T1> src1,
    IEnumerable<T2> src2,
    Func<T1, T2, bool> check)
{
    var list = new List<T2>();
    using(var enumerator = src2.GetEnumerator())
    {
        foreach(var item1 in src1)
        {
            while(enumerator.MoveNext())
            {
                var pickedItem = enumerator.Current;
                if(check(item1, pickedItem))
                {
                    list.Add(pickedItem);
                }
                else
                {
                    break;
                }
            }
            var items = list.ToArray();
            list.Clear();
            yield return new Tuple<T1, IEnumerable<T2>>(item1, items);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它保证两个枚举只被枚举一次。

用法:

var src1 = new int[] { 2, 3, 5, 7, 11 };
var src2 = Enumerable.Range(1, 11);
Func<int, int, bool> predicate = (i1, i2) => i1 > i2;
var result = src1.ConditionalZip(src2, predicate);
Run Code Online (Sandbox Code Playgroud)