Перечисление всех комбинаций списков разных типов - PullRequest
2 голосов
/ 21 апреля 2010

Учитывая два IEnumberable разных типов, какова лучшая практика (учитывая удобочитаемость и удобство сопровождения) для итерации по обоим спискам для выполнения действий со всеми возможными комбинациями?

Мое первоначальное решение состояло в том, чтобы использовать вложенные циклы foreach, повторяя первый IEnumerable, а затем внутри этого цикла, повторяя второй IEnumerable и передавая значение из внешнего и текущего цикла в целевой метод. Eg.:

enum ParamOne
{
    First, 
    Second,
    Etc
}

List<int> paramTwo = new List<int>() { 1, 2, 3 };

void LoopExample()
{
    foreach (ParamOne alpha in Enum.GetValues(typeof(ParamOne)))
    {
        foreach (int beta in paramTwo)
        {
            DoSomething(alpha, beta);
        }
    }
 }

Я попытался реструктурировать его с помощью LINQ, но в итоге получилось нечто, что не имело очевидных преимуществ и казалось менее интуитивным. Поиск здесь показывает много вопросов о вложенных foreachs для итерации по дочерним свойствам, но я не смог найти ничего по поводу итерации по двум различным спискам.

Ответы [ 2 ]

1 голос
/ 21 апреля 2010

Пока нет совпадений в комбинациях, я не вижу более вычислительно эффективного способа вычисления функции на декартовом произведении из двух множеств. Однако, если в любом из списков есть повторяющиеся элементы или порядок аргументов DoSomething не имеет значения и в списках есть совпадения, вы создадите избыточные вызовы DoSomething. Вы можете сэкономить время вычислений, запомнив DoSomething.

1 голос
/ 21 апреля 2010

Я не вижу ничего особенно плохого в вашем решении. При этом простейшая процедура LINQ выглядит так:

foreach(var entry in enumerable1.SelectMany(
            e => enumerable2.Select(e2 => new { First = e, Second = e2 })))
{
    DoSomething(entry.First, entry.Second);
}

Учитывая, что это немного ... тупо ... Я бы рекомендовал придерживаться двух foreach операций. Это дешевле, чем все махинации, которые должен пройти компилятор C #, чтобы заставить это выражение работать (поскольку мы имеем дело как с замыканиями, так и с анонимными типами).

...