Можем ли мы использовать несколько переменных в foreach

Можно ли использовать несколько переменных в foreach

foreach (var item1 in collection1;var items2 in collection2)
{

}

Я хочу сделать это, потому что мне нужно получить две коллекции из базы данных и добавить оба из них в ComboBox.

Ответ 1

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

var col = collection1.Join(collection2, x => x, y => y, (x, y) => new { X = x, Y = y });
foreach (var entry in col) {
    // entry.X, entry.Y
}

Edit:

При отправке ответа я предположил, что collection1 и collection2 содержат разные типы. Если они содержат один и тот же тип или имеют общий базовый тип, существуют альтернативы:

Если вы хотите разрешить дубликаты:

collection1.Concat(collection2); // same type
collection1.select(x => (baseType)x).Concat(collection2.select(x => (baseType)x)); // shared base type

Нет дубликатов:

collection1.Union(collection2); // same type
collection1.select(x => (baseType)x).Union(collection2.select(x => (baseType)x)); // shared base type

Рамка форм 4.0 вперед Zip может заменить исходное решение:

collection1.Zip(collection2, (x, y) => new { X = x, Y = y });

Обзор большинства доступных функций LINQ см. в 101 образцах LINQ.

Без LINQ используйте две иерархические петли foreach (увеличение числа взаимодействий) или один цикл foreach для создания типа inermediate, а второй - для итерации по набору промежуточных элементов или если типы в коллекциях одинаковы, добавьте их в (используя AddRange), а затем повторите этот новый список.

Многие дороги приводят к одной цели... ее до вас, чтобы выбрать ее.

Ответ 2

Вы можете закрепить коллекции

foreach (var item in collection1.Zip(collection2, (a, b) => new {  A = a, B = b }))
{
  var a = item.A;
  var b = item.B;
  // ...
}

Это предполагает, что элементы совпадают в одном и том же положении (например, первый элемент из коллекции1 соединяет первый элемент collectcion2). Это довольно эффективно.

Ответ 3

Нет, вы не можете использовать несколько переменных в foreach, в цикле. Проверьте ссылку ссылку на язык. Что произойдет, если в каждой коллекции будет разное количество элементов?

Если вы хотите перебирать обе коллекции, попробуйте использовать union:

foreach (var item1 in collection1.Union(collection2))
{
   ...
}

Ответ 4

Судя по вашим комментариям, я думаю, что вы действительно пытаетесь сделать, не получить декартово произведение двух коллекций, а [SQL] UNION двух наборов. У вас есть два варианта:

  • Concat две коллекции:

    foreach(var items in collection1.Concat(collection2)) {}
    
  • Просто добавьте их оба отдельно, предполагая, что вам не нужно ничего делать, итерируя (возможно, лучший/самый простой):

    myComboBox.Items.AddRange(collection1);
    myComboBox.Items.AddRange(collection2);
    

Если, однако, вам нужно декартово произведение n * m [SQL псевдокода] collection1 CROSS JOIN collection2, вы должны использовать два вложенных оператора foreach:

foreach(var item1 in collection1)
foreach(var item2 in collection2)
{
}

Или вы можете присоединиться к ним в LINQ и перебрать объединенную коллекцию:

foreach(var items in (from i1 in collection1 
                      from i2 in collection2 
                      select Tuple.Create(i1, i2)))
{
}

Ответ 5

foreach используется для перечисления отдельных элементов в коллекции. Так что ты не можешь. Вы должны использовать его один за другим. Было бы лучше использовать:

void myfunc()
{}

foreach(var item1 in collection1){myfunc();}
foreach(var item2 in collection2){myfunc();}

чем

foreach(var item1 in collection1)
foreach(var item2 in collection2)
{
    myfunc();
}

Это будет работать за n * m раз. Если предыдущий пример выполнялся только для n + m раз.

Ответ 6

Вы хотите соединить элементы из одной коллекции с соответствующими элементами другого?

foreach (var pair in col1.Zip(col2, (Item1, Item2) => new { Item1, Item2 })
{
    //do something with pair.Item1 and pair.Item2
}

Примечание: если первая коллекция имеет 10 элементов, а вторая имеет 8, вы получите 8 пар; последние два элемента в первой коллекции будут отброшены, потому что во второй коллекции их не будет соответствовать. В общем случае число итераций будет Min(col1.Count(), col2.Count()).

Вы хотите перебрать все элементы в одной коллекции, а затем все элементы во втором?

foreach (var element in col1.Concat(col2))
{
    //do something with element
}

Примечание: если первая коллекция имеет 10 элементов, а вторая имеет 8, этот цикл будет выполняться 18 раз или, в более общем плане, число итераций будет col1.Count() + col2.Count().

Вы хотите связать каждый элемент в одной коллекции с каждым элементом в другом?

foreach (var item1 in col1)
    foreach (var item2 in col2)
    {
         //do something with item1 and item2
    }

Примечание: это декартово произведение, поэтому неудивительно, что число итераций является продуктом размеров коллекций. Если у нас есть 10 и 8 элементов, цикл будет выполняться 80 раз. Для обеспечения согласованности это col1.Count() * col2.Count().

Ответ 7

Вы можете использовать итератор:

IEnumerator <Item2Type> item2Itt = Collection2.GetEnumerator();
item2Itt.MoveNext(); // The iterator returned above is BEFORE the first element in the collection.
foreach (Item1Type item1 in collection1)
{
    item1.blahblahblah;
    item2Itt.Current.blahBlahBlah;
    item2Itt.MoveNext();
}

Ответ 8

Я думаю, что этот способ можно использовать:

List<Type> allOfThem = new List<Type>(); //use proper type for collection
allOfThem.AddRange(collection1);
allOfThem.AddRange(collection2);

foreach (Type item in allOfThem)
{
...
}