与python等价的c#版本itertools.izip_longest

本文关键字:itertools izip longest 版本 python | 更新日期: 2023-09-27 18:13:59

我想弄清楚是否有内置支持压缩两个不同长度的IEnumerables,而不会丢失c#中较大列表中的元素。

基本上我正在寻找Python(>= 2.6)版本的izip_longestitertools在c#。

我也开放其他漂亮的自定义解决方案使用LINQ来获得相同的功能。为了进一步说明,

如果a = [1, 2, 3]b = [4, 5, 6, 7],期望的输出应该是[[1, 4], [2, 5], [3, 6], [7]]

与python等价的c#版本itertools.izip_longest

我自己编写了一个遍历IEnumerable<T>的zip扩展方法:

public static IEnumerable<T[]> Zip<T>(this IEnumerable<T> left, IEnumerable<T> right)
{
    IEnumerator<T> leftEnumerator = left.GetEnumerator();
    IEnumerator<T> rightEnumerator = right.GetEnumerator();
    bool hasLeft = leftEnumerator.MoveNext();
    bool hasRight = rightEnumerator.MoveNext();
    while (hasLeft || hasRight)
    {
        if (hasLeft && hasRight)
        {
            yield return new T[] { leftEnumerator.Current, rightEnumerator.Current };
        }
        else if (hasLeft)
        {
            yield return new T[] { leftEnumerator.Current };
        }
        else if (hasRight)
        {
            yield return new T[] { rightEnumerator.Current };
        }
        hasLeft = leftEnumerator.MoveNext();
        hasRight = rightEnumerator.MoveNext();
    }
}

你可以这样调用它:

int[] a = new int[] { 1, 2, 3 };
int[] b = new int[] { 4, 5, 6, 7 };
IEnumerable<int[]> zipped = a.Zip(b);

LINQ本身有一个Zip方法,用于组合两个序列中的元素,并对它们应用一个函数(可以简单地将元素组合成一对)。结果与最短序列一样长。

MoreLINQ库为LINQ添加了几个扩展,包括MaxBy, ExceptBy和各种Zip策略,包括返回最短(Zip),最长(ZipLongest)或不匹配失败(EquiZip)。

文档中的示例显示ZipLongest将返回缺失元素的默认值:

int[] numbers = { 1, 2, 3 };
string[] letters = { "A", "B", "C", "D" };
var zipped = numbers.ZipLongest(letters, (n, l) => n + l);
/// ... will yield "1A", "2B", "3C", "0D" in turn.

您可以从Nuget下载单个操作符(例如ZipLongest)的代码或二进制包,或者您可以下载整个库的二进制包。