Как создать один список пар объектов из двух списков в C #? - PullRequest
12 голосов
/ 18 августа 2011

У меня есть два списка объектов. Список 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)

Ответы [ 4 ]

37 голосов
/ 18 августа 2011

Вы можете использовать метод Enumerable.Zip () в System.Linq.

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 из метода, в котором он создан, из-за того, что тип не имеет имени.

5 голосов
/ 18 августа 2011

Это будет сделано:

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

Редактировать: Я предпочитаю Пол ответ.

3 голосов
/ 18 августа 2011

Примерно так:

 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, а 2, б 3, с

1 голос
/ 18 августа 2011

Я бы предложил использовать Список мячей

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...