简体   繁体   English

如何从 C# 中的两个列表创建单个对象对列表?

[英]How do I create a single list of object pairs from two lists in C#?

I have two lists of objects.我有两个对象列表。 List A and List B. I need to create List C which combines List A and List B into pairs.列表 A 和列表 B。我需要创建将列表 A 和列表 B 组合成对的列表 C。 For example:例如:

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)

You could use the Enumerable.Zip() method in System.Linq.您可以使用 System.Linq 中的Enumerable.Zip()方法。

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB, (a, b) => Tuple.Create(a, b));

Example using this resultant enumerable:使用此结果可枚举的示例:

foreach (Tuple<A, B> pair in pairs)
{
    A a = pair.Item1;
    B b = pair.Item2;
}

Shame there's not an overload that automates the tupleation in .NET.可惜没有在 .NET 中自动进行元组化的重载。 Such an extension would look like this:这样的扩展看起来像这样:

public static IEnumerable<Tuple<TFirst, TSecond>> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
    return first.Zip(second, Tuple.Create);
}

Which would mean you could then write code that looks like:这意味着您可以编写如下代码:

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB);

Note: Another option would be to create anonymous types instead of Tuple but the downside to this approach is that you would not be able to (usefully) pass the resultant IEnumerable out of the method it is created in owing to the type not having a name.注意:另一种选择是创建匿名类型而不是Tuple但这种方法的缺点是您将无法(有用地)将结果 IEnumerable 从它创建的方法中传递出去,因为类型没有名称.

This would do it:这样做:

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)
                );
        }
    }
}

Edit: I vastly prefer Paul's answer.编辑:我非常喜欢保罗的回答。

Something like this:像这样的东西:

 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);
 }

Output: 1,a 2,b 3,c输出:1,a 2,b 3,c

.NET Core 3 has a new overload for the Zip method . .NET Core 3 对 Zip 方法有一个新的重载 It takes two IEnumerables and creates one IEnumerable containing value tuples with the elements from both input IEnumerables.它需要两个 IEnumerable 并创建一个包含值元组的 IEnumerable,其中元素来自两个输入 IEnumerable。

IEnumerable<(A a, B b)> pairs = listA.Zip(listB);

You can use the result in multiple ways:您可以通过多种方式使用结果:

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;
}

I would suggest to use a List of tupples我建议使用元组列表

http://msdn.microsoft.com/en-us/library/system.tuple.aspx . http://msdn.microsoft.com/en-us/library/system.tuple.aspx

A potential solution using System.Linq Enumerable.Zip method (without specifying a function argument Func ) would be as follows (note I've used ints to provide a simple concrete example):使用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));

Outputs:输出:

(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM