如何使用空数组执行 Zip 操作
How to perform Zip operation with null array
我正在 C# 中试验 Zip 操作,如 here 所述。考虑这个代码片段:
int[] numbers = new[] { 1, 2, 3, 4 };
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);
}
如果其中一个组件是 null
,避免 System.ArgumentNullException
的正确方法是什么?
比如初始化words
为null,像这样
int[] numbers = new[] { 1, 2, 3, 4 };
string[] words = null;
// The next line won't work
var numbersAndWords = numbers.Zip(words, (n, w) => new { Number = n, Word = w });
Obs:我实际上正在使用 Directory.EnumerateDirectories
和 Directory.EnumerateFiles
而不是 int[]
和 string[]
.
下面有点难看,但您可以像这样使用空合并运算符 ??
:
var numbersAndWords =
(numbers ?? Enumerable.Empty<int>()).Zip(
(words ?? Enumerable.Empty<string>()),
(n, w) => new { Number = n, Word = w });
或者创建一个扩展方法来做同样的事情(你可能想要一个比 OrEmpty
更好的名字):
public static class MyEnumerableExtensions
{
public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> self)
{
return self ?? Enumerable.Empty<T>();
}
}
var numbersAndWords = numbers.OrEmpty()
.Zip(words.OrEmpty(), (n, w) => new { Number = n, Word = w });
Zip
对于空序列不是很有用,因为它会 return 空序列(它 return 序列基于较短的长度)。您也可以检查一下:
var result = numbers == null || words==null ?
Enumerable.Repeat(new { Number = 0, Word = "" },0) :
numbers.Zip(words, (n, w) => new { Number = n, Word = w });
根据您可能的使用情况,我看不出 Zip
'ing 目录和文件有何用处(忽略痛苦的 "Access denied" 和其他 IO 异常)。可能您想要一个文件列表以及父目录。下面的近似代码(获取每个目录的所有文件,将每个文件与目录信息配对,展平):
var directories = ....
var filesAndDir = directories
.Select(dir => Directory.EnumerateFiles(dir).Select{file => new {dir, file})
.SelectMany(r=>r);
我正在 C# 中试验 Zip 操作,如 here 所述。考虑这个代码片段:
int[] numbers = new[] { 1, 2, 3, 4 };
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);
}
如果其中一个组件是 null
,避免 System.ArgumentNullException
的正确方法是什么?
比如初始化words
为null,像这样
int[] numbers = new[] { 1, 2, 3, 4 };
string[] words = null;
// The next line won't work
var numbersAndWords = numbers.Zip(words, (n, w) => new { Number = n, Word = w });
Obs:我实际上正在使用 Directory.EnumerateDirectories
和 Directory.EnumerateFiles
而不是 int[]
和 string[]
.
下面有点难看,但您可以像这样使用空合并运算符 ??
:
var numbersAndWords =
(numbers ?? Enumerable.Empty<int>()).Zip(
(words ?? Enumerable.Empty<string>()),
(n, w) => new { Number = n, Word = w });
或者创建一个扩展方法来做同样的事情(你可能想要一个比 OrEmpty
更好的名字):
public static class MyEnumerableExtensions
{
public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> self)
{
return self ?? Enumerable.Empty<T>();
}
}
var numbersAndWords = numbers.OrEmpty()
.Zip(words.OrEmpty(), (n, w) => new { Number = n, Word = w });
Zip
对于空序列不是很有用,因为它会 return 空序列(它 return 序列基于较短的长度)。您也可以检查一下:
var result = numbers == null || words==null ?
Enumerable.Repeat(new { Number = 0, Word = "" },0) :
numbers.Zip(words, (n, w) => new { Number = n, Word = w });
根据您可能的使用情况,我看不出 Zip
'ing 目录和文件有何用处(忽略痛苦的 "Access denied" 和其他 IO 异常)。可能您想要一个文件列表以及父目录。下面的近似代码(获取每个目录的所有文件,将每个文件与目录信息配对,展平):
var directories = ....
var filesAndDir = directories
.Select(dir => Directory.EnumerateFiles(dir).Select{file => new {dir, file})
.SelectMany(r=>r);