[英]How do I create a single list of object pairs from two lists in C#?
我有两个对象列表。 列表 A 和列表 B。我需要创建将列表 A 和列表 B 组合成对的列表 C。 例如:
List A
object a1
object a2
object a3
List B
object b1
object b2
object b3
List C (creates pairs)
object c1 (object a1, object b1)
object c2 (object a2, object b2)
object c3 (object a3, object b3)
您可以使用 System.Linq 中的Enumerable.Zip()方法。
IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB, (a, b) => Tuple.Create(a, b));
使用此结果可枚举的示例:
foreach (Tuple<A, B> pair in pairs)
{
A a = pair.Item1;
B b = pair.Item2;
}
可惜没有在 .NET 中自动进行元组化的重载。 这样的扩展看起来像这样:
public static IEnumerable<Tuple<TFirst, TSecond>> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
return first.Zip(second, Tuple.Create);
}
这意味着您可以编写如下代码:
IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB);
注意:另一种选择是创建匿名类型而不是Tuple
但这种方法的缺点是您将无法(有用地)将结果 IEnumerable 从它创建的方法中传递出去,因为类型没有名称.
这样做:
public static IEnumerable<Tuple<T, U>> CombineWith<T, U>(this IEnumerable<T> first, IEnumerable<U> second)
{
using (var firstEnumerator = first.GetEnumerator())
using (var secondEnumerator = second.GetEnumerator())
{
bool hasFirst = true;
bool hasSecond = true;
while (
// Only call MoveNext if it didn't fail last time.
(hasFirst && (hasFirst = firstEnumerator.MoveNext()))
| // WARNING: Do NOT change to ||.
(hasSecond && (hasSecond = secondEnumerator.MoveNext()))
)
{
yield return Tuple.Create(
hasFirst ? firstEnumerator.Current : default(T),
hasSecond ? secondEnumerator.Current : default(U)
);
}
}
}
编辑:我非常喜欢保罗的回答。
像这样的东西:
var listA = new object[] { "1", "2", "3" };
var listB = new object[] { "a", "b", "c" };
var listC = Enumerable.Zip(listA,listB, (x,y)=>new {x,y});
foreach (var item in listC)
{
Console.WriteLine("{0},{1}", item.x,item.y);
}
输出:1,a 2,b 3,c
.NET Core 3 对 Zip 方法有一个新的重载。 它需要两个 IEnumerable 并创建一个包含值元组的 IEnumerable,其中元素来自两个输入 IEnumerable。
IEnumerable<(A a, B b)> pairs = listA.Zip(listB);
您可以通过多种方式使用结果:
foreach((A a, B b) in pairs)
{
// Do something with a and b
}
foreach(var (a, b) in pairs)
{
// Do something with a and b
}
foreach(var pair in pairs)
{
A a = pair.a;
B b = pair.b;
}
使用System.Linq
Enumerable.Zip
方法(不指定函数参数Func
)的潜在解决方案如下(注意我使用 ints 提供了一个简单的具体示例):
List<int> list1 = new List<int>() {1,2,3,4,5};
List<int> list2 = new List<int>() {5,4,3,2,1};
IEnumerable<(int, int)> pairs;
pairs = list1.Zip(list2);
Console.WriteLine(string.Join(", ", pairs));
输出:
(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.