19

foreach で複数の変数を使用できますか

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

}

データベースから 2 つのコレクションをフェッチし、両方を ComboBox に追加する必要があるため、これを実行したいと考えています。

4

9 に答える 9

16

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
}

編集:

回答を投稿するとき、私はそれを想定しcollection1collection2さまざまなタイプが含まれていました。両方に同じ型が含まれているか、共通の基本型を共有している場合は、別の方法があります。

重複を許可する場合:

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 を使用しない場合は、2 つの階層的な foreach ループ (反復回数を増やす) または 1 つの foreach ループを使用して中間型を作成し、2 つ目の foreach ループを使用して中間型のコレクションを反復処理するか、コレクション内の型が同じ場合はそれらをリストに追加します (AddRange)次に、この新しいリストを繰り返し処理します。

多くの道が 1 つの目標に通じています。その 1 つを選択するのはあなた次第です。

于 2013-01-25T06:32:23.850 に答える
6

コレクションを圧縮できます

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

これは、要素が同じ位置で一致することを前提としています (たとえば、collection1 の最初の要素が、collection2 の最初の要素を結合します)。それは非常に効率的です。

于 2013-01-25T06:52:36.620 に答える
3

いいえ、ループ内の foreach で複数の変数を使用することはできません。言語リファレンスを確認してください。各コレクションのアイテム数が異なる場合はどうなるでしょうか?

両方のコレクションを反復処理する場合は、ユニオンを使用してみてください。

foreach (var item1 in collection1.Union(collection2))
{
   ...
}
于 2013-01-25T06:31:30.157 に答える
1

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 回だけ実行されます。

于 2013-01-25T06:42:06.100 に答える
1

あなたのコメントから判断すると、あなたが本当にやろうとしていることは、2 つのコレクションのデカルト積を取得することではなくUNION、2 つのセットの [SQL] を取得することだと思います。次の 2 つのオプションがあります。

  1. Concat2 つのコレクション:

    foreach(var items in collection1.Concat(collection2)) {}
    
  2. 繰り返して派手なことをする必要がないと仮定して、両方を別々に追加するだけです(おそらく最良/最も単純です):

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

ただし、 [SQL pseudocode] の n*m デカルト積が必要なcollection1 CROSS JOIN collection2場合は、ネストされた 2 つの foreach ステートメントを使用します。

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

または、LINQ で 2 つを結合し、結合されたコレクションを反復処理できます。

foreach(var items in (from i1 in collection1 
                      from i2 in collection2 
                      select Tuple.Create(i1, i2)))
{
}
于 2013-01-25T06:32:45.610 に答える
0

あるコレクションのアイテムを他のコレクションの対応するアイテムとペアリングしますか?

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

注: 最初のコレクションに 10 個のアイテムがあり、2 番目のコレクションに 8 個のアイテムがある場合、8 つのペアが得られます。最初のコレクションの最後の 2 つのアイテムは、2 番目のコレクションに一致するものがないため削除されます。より一般的には、反復回数は になりますMin(col1.Count(), col2.Count())

1 つのコレクションのすべてのアイテムを反復処理してから、2 番目のコレクションのすべてのアイテムを反復処理しますか?

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

注: 最初のコレクションに 10 個の要素があり、2 番目のコレクションに 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().

于 2013-01-25T07:28:20.147 に答える