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

Ear*_*arl 14 c# list object

我有两个对象列表.列表A和列表B.我需要创建列表C,它将列表A和列表B组合成对.例如:

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)
Run Code Online (Sandbox Code Playgroud)

Pau*_*ane 40

您可以在System.Linq中使用Enumerable.Zip()方法.

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB, (a, b) => Tuple.Create(a, b));
Run Code Online (Sandbox Code Playgroud)

使用此结果可枚举的示例:

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

遗憾的是,没有一个重载可以自动化.NET中的元组.这样的扩展看起来像这样:

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

这意味着您可以编写如下代码:

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB);
Run Code Online (Sandbox Code Playgroud)

注意:另一种选择是创建匿名类型,而不是Tuple这种方法的缺点是,由于类型没有名称,您将无法(有用地)将生成的IEnumerable传递给它创建的方法.

  • *请注意,在2018年您现在可以执行:`listA.Zip(listB,(a,b)=&gt; Tuple.Create);` (2认同)

Jon*_*son 5

这样做:

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)
                );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我非常喜欢保罗的回答.