Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Zip()合并不同长度的数组而不丢失值_C#_.net_Arrays_Linq - Fatal编程技术网

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

C# 使用Zip()合并不同长度的数组而不丢失值,c#,.net,arrays,linq,C#,.net,Arrays,Linq,在下面的代码中,我将合并两个类型为int和string的数组。第一个索引的长度大于第二个索引的长度,因此,最后一个索引(即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, Wo

在下面的代码中,我将合并两个类型为
int
string
的数组。第一个索引的长度大于第二个索引的长度,因此,最后一个索引(即
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
字符串之后创建一个
null或空字符串,并使用它与最后一个
数字
索引合并。我想不出来

编辑: 我得到的结果

1one
2two
3three
4four
我想要的结果

1one
2two
3three
4four
5
谢谢


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

在压缩之前,您可以扩展两个集合中较小的集合,例如:

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

IEnumerable<string> wordsExtended = words;

if(words.Length < numbers.Length)
{
    wordsExtended = words.Concat(Enumerable.Repeat("", numbers.Length - words.Length));
}

var numbersAndWords = numbers.Zip(wordsExtended, (n, w) => new { Number = n, Word = w });
foreach (var nw in numbersAndWords)
{
    Console.WriteLine(nw.Number + nw.Word);
}
int[]number=new[]{1,2,3,4,5};
字符串[]字=新字符串[]{“一”、“二”、“三”、“四”};
IEnumerable words趋势=单词;
if(字.长度<数字.长度)
{
wordsExtended=words.Concat(可枚举的重复(“,number.Length-words.Length));
}
var numbersAndWords=numbers.Zip(wordsTrend,(n,w)=>new{Number=n,Word=w});
foreach(数值和文字中的变量nw)
{
控制台写入线(nw.Number+nw.Word);
}
理想情况下,您希望将其封装在实用程序方法中,并且是泛型的,以便它适用于任何压缩的集合


看起来有人已经为此编写了一个通用实现。

您可以轻松编写自己的类似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);
                }
            }
        }
    }
}

这是一种非对称解决方案,它使用第一个序列作为锚,在可用时将第二个序列中的对应元素配对,或者使用默认值。不需要计算长度,也不需要提前强制计算枚举数

向IEnumerable添加扩展名:

public static class EnumerableExtensions {
        

    public static IEnumerable<T> PadRight<T>(this IEnumerable<T> s)
    {
        foreach (var t in s)
            yield return t;

        while (true)
            yield return default(T);
     }
}

您链接到的答案的问题是,它将导致源集合上出现多个枚举(因为
Count
调用。当使用数组作为源时,这并不重要,但当使用不同的源时,这可能很重要。这只有在您事先知道哪些输入较短时才起作用。它要求您通过调用此
PadRight()显式处理较短的输入)
方法。与公认的答案相比,这似乎是一个明显较差的解决方案。我无法想象有人会选择它而不是更好、更通用的解决方案。事实上,这个答案几乎与相同,有许多相同的缺点。感谢建设性的批评。我将您的评论作为参考注意。我确实指出,建议的解决方案不需要强制枚举惰性序列(以计算长度)。因此,对于某些应用程序,它可能更有效。“建议的解决方案不需要强制枚举惰性序列”--当然可以,但公认的解决方案也不需要,也不需要像您的解决方案那样提前知道哪个序列会更短。
public static class EnumerableExtensions {
        

    public static IEnumerable<T> PadRight<T>(this IEnumerable<T> s)
    {
        foreach (var t in s)
            yield return t;

        while (true)
            yield return default(T);
     }
}
int[] numbers = new[] { 1, 2, 3, 4, 5 };
string[] words = new string[] { "one", "two", "three", "four" };

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