foreachを最初に使用した以外の要素から反復を開始することは可能ですか?


86

カスタムコレクション(ツリー)にIEnumerableを実装して、foreachを使用してツリーをトラバースできるようにすることを考えています。ただし、私が知る限り、foreachは常にコレクションの最初の要素から始まります。foreachが開始する要素を選択したいと思います。foreachが始まる要素をどうにかして変更することは可能ですか?


1
私は驚き最小の原則に従います:en.wikipedia.org/wiki/Principle_of_least_astonishment
ChaosPandion 2011年

最初の要素から始めない場合、イテレータの動作をどのように定義しますか?シーケンスの最後に達するとどうなりますか?次に、最初の要素に戻り、残りの要素を繰り返し処理しますか?
ダンJ

@ChaosPandionのコメントは、私がそれらの質問に取り組んでいたところです。:)
ダンJ

回答:


162

はい。以下をせよ:

Collection<string> myCollection = new Collection<string>;

foreach (string curString in myCollection.Skip(3))
    //Dostuff

SkipはIEnumerable関数であり、現在のインデックスから指定した数をスキップします。一方、最初の3つだけを使用したい場合、次を使用します.Take

foreach (string curString in myCollection.Take(3))

これらはペアにすることもできるので、4〜6個のアイテムだけが必要な場合は、次のことができます。

foreach (string curString in myCollection.Skip(3).Take(3))

よろしくお願いします。StackoverflowでWTBオートコンプリート(gahhは実際の名前を思い出せません);)
MoarCodePlz 2011年

これは実際にスキップしますか、それとも単にコピーを作成するだけですか?IEはこれら2つが異なるでしょう:foreach(List<string> row in rows.skip(1)){ row[0] = "newInfo"; } vs for(int i=1; i<rows.Count;i++){ List<string> row = rows[i]; row[0] = "newStuff"; }
TigerBear 2016年

25

SkipこのためにLINQto Objectsのメソッドを使用して、指定された数の要素をスキップするのが最も簡単です。

foreach (var value in sequence.Skip(1)) // Skips just one value
{
    ...
}

明らかに、他の値の1を変更して、異なる数の要素をスキップします。

同様にTake、返される要素の数を制限するために使用できます。

これらの両方(および関連するメソッドSkipWhileTakeWhileメソッド)の詳細については、Edulinqブログシリーズを参照してください


ジョン、「シーケンス」がNullの場合、これは例外のリスクを冒しませんか?
WEFX 2015

@WEFX:sequence合法的にできるかどうかはわかりnullません。おそらく、OPはそれを自分で処理できます-それは実際には問題の一部ではありません...
Jon Skeet 2015

5

Enumerable.Skipを使用できますを、一部の要素をスキップし、そこから開始。

例えば:

foreach(item in theTree.Skip(9))  // Skips the first 9 items
{
    // Do something

ただし、ツリーを作成している場合は、ツリーアイテム自体にメンバーを指定して、IEnumerable<T>そこから列挙する新しいメンバーを返すことができます。これは、潜在的に、長期的にはより有用です。


のようなものIEnumerable<T> SubTree(rootIndex)?グッドコール!
ダンJ

答えてくれてありがとう、スキップは有望に見えます。スキップに関するMSDN情報を読んで、IEnumerable <MyTree>の拡張メソッドとなるメソッドStartFrom(このIEnumerable <MyTree>ツリー、MyTreeElement要素)を作成できる可能性があるという結論に達しました。 IEnumerable <MyTreeElement>が返され、そこから反復を開始する必要があります。次に、このメソッドをforeach(tree.StartFrom(someElement))のvar要素として使用できます。
インフェルノ2011年

@inferno:はい、簡単にできます。ただし、MyTreeElementに次のようなメソッド/プロパティを追加するだけなIEnumerable<MyTreeElement> Childrenので、次のことができます 。-foreach(var item in someElement.Children)拡張メソッドIMOを使用するよりもはるかに明確です。
リードコプシー2011年

-1

Foreach の実装によって定義された方法でコレクションを反復処理します IEnumerable。したがって、要素をスキップすることはできますが(上記で提案したように)、技術的には同じ順序で要素を反復処理しています。

何を達成しようとしているのかわかりませんが、クラスに複数のIEnumerableプロパティがあり、それぞれが特定の順序で要素を列挙している可能性があります。


-1

の行の読み取りをスキップしたい場合はDataGridView、これを試してください

foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow().Skip(3))

DataGridView行をスキップして1つのコンテンツを別のコンテンツにコピーする場合は、これを試してください。

foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow>().Skip(3))
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        string value = cell.Value.ToString();
        dataGridView2.Rows[i].Cells[j].Value = cell.Value.ToString();
        j++;
    }
    i++;
    j = 0;
}

これにより、DataGridView3行をスキップしてコンテンツがコピーされます。


これは、尋ねられた質問には答えません-質問はまったく言及DataGridViewしていません(またはUIフレームワークさえも)。
nightOwl888 2018

@ NightOwl888これは、質問がいくつかの反復をスキップし、その後foreachループで反復することに関するものであったために回答されました。私の例では、Skip()を使用してDataGridViewに適用しました。
Juned Khan Momin 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.