簡體   English   中英

如何從 C# 中的兩個列表創建單個對象對列表?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM