c# - 使用 Zip() 合并不同长度的数组而不丢失值

标签 c# .net arrays linq

在下面的代码中,我合并了两个 intstring 类型的数组。第一个的长度大于第二个,因此,最后一个索引(5)不会被合并:

int[] numbers = new[] { 1, 2, 3, 4, 5 };
string[] words = new string[] { "one", "two", "three", "four" };

var numbersAndWords = numbers.Zip(words, (n, w) => new { Number = n, Word = w });
foreach (var nw in numbersAndWords)
{
    Console.WriteLine(nw.Number + nw.Word);
}

我想知道一种合并它的方法。例如,在 words 中存在的最后一个之后创建一个 null 或空字符串,并使用它与最后一个 numbers 索引合并。想不通。

编辑: 我得到的结果

1one
2two
3three
4four

我想要的结果

1one
2two
3three
4four
5

谢谢!

编辑:不是重复的,我的另一个问题是关于在空对象上调用方法。

最佳答案

您可以轻松编写您自己的类似 LINQ 的扩展方法来执行此操作:

public static class MyEnumerable
{
    public static IEnumerable<TResult> ZipWithDefault<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
    {
        bool firstMoveNext, secondMoveNext;

        using (var enum1 = first.GetEnumerator())
        using (var enum2 = second.GetEnumerator())
        {
            while ((firstMoveNext = enum1.MoveNext()) & (secondMoveNext = enum2.MoveNext()))
                yield return selector(enum1.Current, enum2.Current);

            if (firstMoveNext && !secondMoveNext)
            {
                yield return selector(enum1.Current, default(TSecond));
                while (enum1.MoveNext())
                {
                    yield return selector(enum1.Current, default(TSecond));
                }
            }
            else if (!firstMoveNext && secondMoveNext)
            {
                yield return selector(default(TFirst), enum2.Current);
                while (enum2.MoveNext())
                {
                    yield return selector(default(TFirst), enum2.Current);
                }
            }
        }
    }
}

但是如果你的源总是一对数组,简单地使用 for 循环可能会更容易:

public static IEnumerable<TResult> ZipWithDefault<TFirst, TSecond, TResult>(this TFirst[] first, TSecond[] second, Func<TFirst, TSecond, TResult> selector)
{
    var maxLength = Math.Max(first.Length, second.Length);

    for(var i = 0; i < maxLength; i++)
    {
        var firstItem = i < first.Length ? first[i] : default(TFirst);
        var secondItem = i < second.Length ? second[i] : default(TSecond);
        yield return selector(firstItem, secondItem);

    }
}

关于c# - 使用 Zip() 合并不同长度的数组而不丢失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30043859/

相关文章:

c# - 通过 google S3 api 访问存储桶

c# - 在 MVC3 中的布局文件中显示帐户信息的最佳方式

java - 数组中的多态子类对象方法不起作用

c# - vstest.console 可以通过提供特征来过滤测试运行吗?

c# - 强类型数据集作为用户定义的表类型参数

c# - MySQL 查询从组合框中选择

c# - 数组比较作为 C# 中的字典键

数组中元素的计数

c# - 将内联表值函数与 Linq 和 Entity Framework Core 结合使用

c# - 重复 ViewComponent 数据