C# 中的 `Zip` 函数
一句话概括
Zip
函数就像是一个 “拉链”,它把两个序列(比如两个数组或列表)像拉链的左右两齿一样,一对一地配对结合,生成一个新的序列。
一个生动的例子:做三明治
想象一下,你要做一堆三明治。你有两堆原料:
- 第一堆:面包片
[ "片1", "片2", "片3" ]
- 第二堆:火腿片
[ "火腿1", "火腿2", "火腿3" ]
你的目标是:把每一片面包和一片火腿组合起来。
没有 Zip
的时候,你可能要写一个循环,手动从两个数组里取相同位置的元素来组合。
有了 Zip
之后,这个过程变得非常简单:
// 1. 准备原料
string[] breads = { "片1", "片2", "片3" };
string[] hams = { "火腿1", "火腿2", "火腿3" };
// 2. 使用 Zip “拉”一下,组合它们!
// 它的作用是:从 breads 取第一个元素,从 hams 取第一个元素,交给后面的函数 (b, h) => ... 去处理
// 然后取第二个,第二个...直到其中一个序列没有元素为止。
var sandwiches = breads.Zip(hams, (b, h) => $"{b} + {h} = 一个三明治");
// 3. 看看我们做了哪些三明治
foreach (var sandwich in sandwiches)
{
Console.WriteLine(sandwich);
}
输出结果:
片1 + 火腿1 = 一个三明治
片2 + 火腿2 = 一个三明治
片3 + 火腿3 = 一个三明治
看!Zip
函数自动帮你把两堆原料按顺序完美地配对组合了。
关键点(拉链的特性)
- 一对一配对:它严格按顺序将第一个序列的第1个元素与第二个序列的第1个元素配对,然后是第2个配第2个,以此类推。
- 长度以短的为准:如果两个序列长度不一样(比如面包有5片,火腿只有3片),
Zip
会配对到较短的那个序列结束为止。剩下的多余元素会被忽略。就像拉链,一边没了,拉链也就拉到头了。 - 你可以定义如何组合:例子中的
(b, h) => $"{b} + {h} ..."
是一个函数,它定义了如何组合每一对元素。你可以在这里做任何事,比如返回一个对象、进行数学计算等等。
另一个实用例子:数学计算
假设有两个数组,你想计算它们的对应项之和。
int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 10, 20, 30 };
// 使用 Zip 将对应位置的数字相加
var sums = numbers1.Zip(numbers2, (a, b) => a + b);
foreach (var sum in sums)
{
Console.WriteLine(sum); // 输出:11, 22, 33
}
总结
特性 | 解释 |
---|---|
作用 | 将两个序列中对应位置的元素配对组合。 |
像什么 | 像一个拉链,把两排齿一一扣在一起。 |
输入 | 两个序列(IEnumerable<T> )。 |
输出 | 一个新的序列,其元素是每对元素根据你提供的规则组合后的结果。 |
长度处理 | 结果序列的长度等于两个输入序列中较短的那个的长度。 |
核心参数 | 一个选择器函数,你用它来告诉 Zip 如何组合每一对元素。 |
希望这个解释能让你彻底明白 Zip
的用法!