如何使用 Zip<TFirst,TSecond>(IEnumerable<TFirst>, IEnumerable<TSecond>)?



我想遍历两个相同长度的列表,并为这些列表的每个成员分配一个各自的变量,而不是在for循环中使用索引。

https://learn.microsoft.com/en us/dotnet/api/system.linq.enumerable.zip?view=net - 5.0

在微软的文档中,第一个应用程序有一个示例,我知道如何使用它,然而,我似乎无法使第二个应用程序工作,而它正是我正在解决的问题所需要的。

下面是一个示例代码来说明:

var numbers = new List<int> { 1, 2, 3 };
var words = new List<string> { "one", "two", "three" };
foreach (var (number, word) in Zip(numbers,words))   //this doesn't work
{
//do something
}
然而,上面的代码抛出了多个错误。我试图操纵它,让它看起来像微软文档中的例子,我让它工作。但是,从下面的示例代码中可以看到,它看起来太冗余了:
var numbers = new List<int> { 1, 2, 3 };
var words = new List<string> { "one", "two", "three" };
foreach (var (number, word) in numbers.Zip(words, (number,word) => (number,word))) //this lambda expression looks too repetitive
{
//do something
}
谁能帮我清理一下吗?

Enumerable.Zip

生成包含两个指定元素的元组序列序列。

你需要使用

Enumerable.Zip(numbers,words)

或扩展方法

numbers.Zip(words)

同样解构的元组var (first, second)c# 7.0或更高版本的

var numbers = new List<int> { 1, 2, 3 };
var words = new List<string> { "one", "two", "three" };
foreach (var (first, second) in numbers.Zip(words)) 
Console.WriteLine($"{first},{second}");

1,one
2,two
3,three

演示


如果您使用的是old and bust。. Net Framework或pre. Net core 3,那么除了使用Func参数之外,你没有太多的选择。然而,你可以使用一个隐蔽的选择器方法,委托,局部方法等

给定

private static (T1, T2) Selector<T1,T2>(T1 t1, T2 t2) => (t1, t2);

使用

foreach (var (i, s) in numbers.Zip(words,Selector)) 

或者直接编写自己的扩展方法

public static IEnumerable<(TFirst,TSecond)> Zip<TFirst, TSecond>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second)
=> first.Zip(second, (first1, second1) => (first1, second1));

如果你想把它作为一个方法而不是一个扩展方法首先你需要使用三个参数:

Zip<TFirst,TSecond,TResult>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst,TSecond,TResult>)

第三个是Func。所以基本上第二段代码的效果是:

int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };    
Func<int, string, (int, string)> func = (integer, str) => (integer, str);
var numbersAndWords = Enumerable.Zip(numbers, words, func);
foreach (var item in numbersAndWords)
{
//do smth
Console.WriteLine(item);
}

。. NET core根据需要接受两个参数:

int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
var numbersAndWords = Enumerable.Zip(numbers, words);
foreach (var item in numbersAndWords)
{
//do smth
Console.WriteLine(item);
}

最新更新