どのように各(VB.NET)の場合の最後のループを見つけるのですか?
質問
私はVB.NETでFor Eachステートメントの最後のループにいる場合はどうすれば確認できますか?
解決
一般的に、あなたは実装上For Each
を実行できる上、コレクション IEnumerator
インターフェース。このインタフェースは、二つの方法、MoveNext
とReset
と1つの特性を有する、Current
。
For Each
を使用する場合、基本的に、それはMoveNext
関数を呼び出し、戻り値を読み取ります。返された値がTrue
であれば、それは、コレクションや要素内の有効な要素はCurrent
プロパティを介して返される存在することを意味します。コレクションにそれ以上の要素がない場合は、MoveNext
機能はFalse
を返し、反復が終了します。
以上の説明から、それはFor Each
は、コレクション内の現在位置を追跡し、そうしないことは明らかであるのあなたの質問への答えは短く、のないののです。
は、次のコードを試すことができます。現在のアイテムが最後の項目である場合には(LINQを使用して)チェックします。
For Each item in Collection
If item Is Collection.Last Then
'do something with your last item'
End If
Next
他のヒント
おそらくだけではなく、foreachのループのために使用することが容易になるだろう。しかし、同様に、あなたはあなたのforeachループ内のカウンタを維持し、yourCollection.Count - 1
への等しいが、その後、あなたが最後の反復であるかどうかを確認できます。
foreachのを使用すると、(すなわち。あなたは蚊帳の外にいる)、これを知ることはできません。
注、私はあなたが唯一のIEnumerableインターフェイスを持っているものを使用していると仮定しています。あなたは、リスト、配列などを持っている場合はそこであり、したがって、あなたはあなたがコレクションのどこにいるかを追跡することができますどのように多くのアイテムを見つけるために.Countまたは類似を使用するここでは他の回答に従っています。
しかし、単にIEnumerableを/ IEnumeratorをして、あなたはforeachのを使用している場合、より多くのある天気を確認してくださいかないために知る方法はありません。
あなたがこれを知っておく必要がある場合は、、foreachのが何をするかである、IEnumerableを自分で使用します。
以下のソリューションは、C#のためですが、VB.NETに簡単に変換する必要があります:
List<Int32> nums = new List<Int32>();
nums.Add(1);
nums.Add(2);
nums.Add(3);
IEnumerator<Int32> enumerator = nums.GetEnumerator();
if (enumerator.MoveNext())
{
// at least one value available
while (true)
{
// make a copy of it
Int32 current = enumerator.Current;
// determine if it was the last value
// if not, enumerator.Current is now the next value
if (enumerator.MoveNext())
{
Console.Out.WriteLine("not last: " + current);
}
else
{
Console.Out.WriteLine("last: " + current);
break;
}
}
}
enumerator.Dispose();
このは印刷されます:
not last: 1
not last: 2
last: 3
トリックは、その後、現在の値のコピーをとり、次のいずれかに移動しようとする列挙子を依頼することです。それが失敗した場合、あなたが作成したコピーは、確かに最後の値だった、そうでない場合よりがあります。
短い答え:することはできません。
長い答え:あなたは、最初の最後または任意の特定の反復を実行しているかどうかを識別することができますFor Eachステートメントの意味で何もありません。
それぞれのためには、IEnumerableをとIEnumerableを<>インターフェースに建てられ、そして行動はあなたが呼んでいるの実装に依存しています。それは混乱しても、コレクションのためにあなたは異なる順序で毎回の要素を返すために反復している、有効です。幸い、リスト<>これを行いません。
あなたが本当に特定の反復が最後であることを知っておく必要がある場合は、、あなたは(事前に)最後の要素を特定することができましたし、その要素に遭遇したときに異なる行動を取るます。
簡単(ブールを通じて、たとえば)の最初のの反復を検出し、別の何かをすることです。
例(C#のが、VBは同様であろう)。
StringBuilder result = new StringBuilder();
bool firstTime = true;
foreach(string s in names)
{
if (!firstTime)
{
result.Append(", ");
}
result.Append(s);
firstTime = false;
}
要素は、コンテナの最後の要素であるかどうかをチェックします。
なぜあなたはそれをしたいですか?
あなただけのループの後の指示を置くことができます。 (あなたが最後の要素に実行されるように)
しかしあなたが
のような何かを行うことができ、代わりにforeachのループのために使用することが容易になるだろうIf item.Equals(itemCollection(itemCollection.Count)) Then
...
End If
あなたのforeachループの内側に...オブジェクトが正しくEqualsメソッドをオーバーライドしていると仮定します。
これはおそらくループのために使用するか、別の変数に現在のインデックスを追跡するよりもはるかに多くのリソースを大量に消費されます。
これは正しい構文である場合は、私はわからないんだけど、それは私はVBを使用していたので、長い時間がかかった。
あなたがすることはできませんループ「の各ページの」標準を使用します。ループ「の各用」の意図は、あなたが基になるコレクションの代わりにデータに集中できるようにすることです。
私はこの投稿に帰ってくるので、私は座って、この問題を考えることにしましたし、私はこの思い付います:
For Each obj In myCollection
Console.WriteLine("current object: {0}", obj.ToString)
If Object.ReferenceEquals(obj, myCollection.Last()) Then
Console.WriteLine("current object is the last object")
End If
Next
あなたがしたい場合は、あなたも、単一の行にIf...Then...End If
文を減らすことができます。反復ごとに.Last()
を呼び出すと、パフォーマンスに大きな影響を持っている場合、私はわからないんだけど、それはあなたが夜に目を覚まし続けるものだならば、あなたは常にループの変数外に割り当てることができます。
このコードサンプルが役立つかもしれません。
For Each item in Collection
If ReferenceEquals(Collection.Item(Collection.Count - 1), item) Then
'do something with your last item'
End If
Next
あなたは、IEnumerableをに縛られている場合。あなたは、foreachループの内側になる必要がありますか?そうでない場合、あなただけのforeachループの前に変数を宣言することができます。ループの中にそれを設定します。 (そのnullでない場合)、次に、ループの後にそれを使用する
さて、いくつかの回避策があります あなたが
CheckBoxListので作業していると仮定次に、このコードサンプルは役立つかもしれない:
Dim count As Integer = 0
Dim totalListCount As Integer = CheckBoxList.Items.Count()
For Each li In CheckBoxList.Items
count += 1
// This is the Last Item
If count = totalListCount THEN
// DO Somthing.....
END IF
NEXT
ここで私はそれが政治的に正しいかどうかを知りいけない単純なことですが、それは動作します。
for each item in listOfThings
if(item = listOfThings.last)then
'you found the last loop
end if
next