Как наиболее элегантно перебирать параллельные коллекции в C #? - PullRequest
4 голосов
/ 02 декабря 2009
        var a = new Collection<string> {"a", "b", "c"};
        var b = new Collection<int> { 1, 2, 3 };

Каков самый элегантный способ итерации по обоим результатам с набором результатов «a1», «b2», «c3»?

Ответы [ 4 ]

13 голосов
/ 02 декабря 2009

Это известно как "zip" или "zip joining" две последовательности. Эрик Липперт описывает этот самый алгоритм и предоставляет реализацию.

4 голосов
/ 02 декабря 2009

Могучий Барт де Смет говорит о функциях почтового индекса здесь:

http://community.bartdesmet.net/blogs/bart/archive/2008/11/03/c-4-0-feature-focus-part-3-intermezzo-linq-s-new-zip-operator.aspx

Его наиболее элегантное решение использует перегрузку выбора, которая принимает 2-параметрический делегат Func в качестве параметра.

a.Select((t,i)=>new{t,i});

В этом примере я просто представляю индекс обрабатываемого элемента. Таким образом, вы можете создать 2 новых перечисления этих анонимных объектов и присоединиться к ним в i.

С точки зрения производительности, я бы пошел с более очевидным циклом урожайности.

3 голосов
/ 02 декабря 2009

В дополнение к замечательным постам Эрика и Барта, вот реализация с использованием операторов System.Linq 3.5:

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (
    this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> resultSelector)
{
    return from aa in a.Select((x, i) => new { x, i })
           join bb in b.Select((y, j) => new { y, j })
             on aa.i equals bb.j
           select resultSelector(aa.x, bb.y);
}
1 голос
/ 02 декабря 2009

Вы можете создать блок итератора для элегантной обработки:

public static class Ext
{
    public static IEnumerable<string> ConcatEach(this IEnumerable a,
       IEnumerable b)
    {
        var aItor = a.GetEnumerator();
        var bItor = b.GetEnumerator();

        while (aItor.MoveNext() && bItor.MoveNext())
            yield return aItor.Current.ToString() + bItor.Current;
    }
}

Назови это элегантно =) как:

var a = new Collection<string> {"a", "b", "c"};
var b = new Collection<int> {1, 2, 3};
foreach(var joined in a.ConcatEach(b))
{
    Console.WriteLine(joined);
}
...