给定的是两个IEnumerable<A> a
和IEnumerable<B> b
。保证它们的长度相同。我想创建一个新IEnumerable<C> c
的,其中每个项目c_i
都是使用Func<A, B, C> f
by派生的c_i := f (a_i, b_i)
。
我能想到的最好的办法是手动同时枚举两个源并产生当前结果,作为扩展方法实现。在 .NET >= 4.0 中没有自定义代码的情况下是否有一种简短的方法?
给定的是两个IEnumerable<A> a
和IEnumerable<B> b
。保证它们的长度相同。我想创建一个新IEnumerable<C> c
的,其中每个项目c_i
都是使用Func<A, B, C> f
by派生的c_i := f (a_i, b_i)
。
我能想到的最好的办法是手动同时枚举两个源并产生当前结果,作为扩展方法实现。在 .NET >= 4.0 中没有自定义代码的情况下是否有一种简短的方法?
使用Zip
方法。
http://msdn.microsoft.com/en-us/library/dd267698.aspx
将指定的函数应用于两个序列的相应元素,生成结果序列。
int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second);
foreach (var item in numbersAndWords)
Console.WriteLine(item);
// This code produces the following output:
// 1 one
// 2 two
// 3 three
Zip 扩展方法的替代解决方案可以使用嵌套的 Select 和 SelectMany 来展平结果。实现应该只采用列表中具有相同索引的元素(而不是叉积):
private int fun(int a, int b)
{
return a * b;
}
var l1 = new List<int> { 1, 2, 3 };
var l2 = new List<int> { 4, 5, 6 };
var r = l1.Select((e1, i1) => l2.Select ((e2, i2) => i1 == i2 ? fun(e1, e2) : 0))
.SelectMany (flat => flat)
.Where(re => re != 0)
.ToList();
这种情况下的输出是:
4
10
18
您可以使用Enumerable.Zip。给定一个函数f(A, B)
,你会有
var c = a.Zip(b, (aItem, bItem) => f(aItem, bItem));