簡體   English   中英

如何知道這是循環的最后一次迭代?

[英]How to Know This is the Last Iteration of a Loop?

有沒有一種奇特的方法可以在不使用計數器的情況下知道您在 List 的最后一個循環中

List<string> myList = new List<string>() {"are", "we", "there", "yet"};

foreach(string myString in myList) {
    // Is there a fancy way to find out here if this is the last time through?
}

不,您必須為此使用常規for(int i=0; i<myList.Length; i++) {... }循環。

改用 for 循環怎么樣?

List<string> myList = new List<string>() {"are", "we", "there", "yet"};

for (var i=0; i<myList.Count; i++)
{
   var myString = myList[i];
   if (i==myList.Count-1)
   {
      // this is the last item in the list
   }
}

foreach很有用 - 但如果您需要記錄您正在做的事情,或者按計數索引事物,那么只需恢復到一個好的舊for循環。

我有兩種方法可以做到。

首先,使用for循環而不是foreach

for(int i = 0; i < myList.Count; i++)
{
    string myString = myList[i];
    bool isLast = i == myList.Count - 1;

    ...
}

或者,如果這需要與枚舉器一起使用,請更改事物的順序。 通常MoveNext是作為 while 循環的控制來完成的,但是如果我們在循環的開頭就這樣做,我們可以使用它的返回來確定我們是否在列表的末尾。

IEnumerator<string> enumerator = myList.GetEnumerator();
bool isLast = !enumerator.MoveNext();
while(!isLast)
{
    string myString = enumerator.Current;
    isLast = !enumerator.MoveNext();

    ...
}

沒有有效的方法來做到這一點。

只需使用for循環和索引。 它以任何方式運行得更快。

不,沒有,如果要使用foreach ,則必須使用計數器。

使用for運算符而不是 foreach

嗯......沒有辦法知道這一點。 不像你想象的那么容易。 列表數據結構只是一種逐個排序項目的方法。 但是您無法僅使用 foreach 結構來判斷一個項目是否是最后一個項目。 最好用於具有 count 屬性的結構,以了解您是否點擊了最后一個(或上一個)項目。

var length = list.Count;

for (var idx = 0; idx < list.Count; idx++)
{
    if (idx == (length - 1))
    {
        // The last item. Do something
    }
}

希望能幫助到你。

“花哨”的方式是保持 1 個元素的前瞻,但你到底為什么要這樣做? 只要保持計數。 這是花哨的方式。 沒有計數器,沒有檢查 Count 屬性。 它只使用一個枚舉器:

using System;
using System.Collections.Generic;

namespace Sandbox
{
  class Program
  {

    enum ListPosition : byte
    {
      First     = 0x01       ,
      Only      = First|Last ,
      Middle    = 0x02       ,
      Last      = 0x04       ,
      Exhausted = 0x00       ,
    }

    private static void WalkList( List<int> numbers )
    {
      List<int>.Enumerator numberWalker = numbers.GetEnumerator();
      bool                 currFetched  = numberWalker.MoveNext();
      int                  currValue    = currFetched ? numberWalker.Current : default( int );
      bool                 nextFetched  = numberWalker.MoveNext();
      int                  nextValue    = nextFetched ? numberWalker.Current : default( int );
      ListPosition         position     ;

      if      (   currFetched &&   nextFetched ) position = ListPosition.First     ;
      else if (   currFetched && ! nextFetched ) position = ListPosition.Only      ;
      else if ( ! currFetched                  ) position = ListPosition.Exhausted ;
      else throw new InvalidOperationException( "Reached Unreachable Code. Hmmm...that doesn't seem quite right" );

      while ( position != ListPosition.Exhausted )
      {
        string article = ( position==ListPosition.Middle?"a":"the" );

        Console.WriteLine( "  {0} is {1} {2} item in the list" , currValue , article , position );

        currFetched = nextFetched ;
        currValue   = nextValue   ;

        nextFetched = numberWalker.MoveNext()                         ;
        nextValue   = nextFetched?numberWalker.Current:default( int ) ;

        if      (   currFetched &&   nextFetched ) position = ListPosition.Middle    ;
        else if (   currFetched && ! nextFetched ) position = ListPosition.Last      ;
        else if ( ! currFetched                  ) position = ListPosition.Exhausted ;
        else throw new InvalidOperationException( "Reached Unreachable Code. Hmmm...that doesn't seem quite right" );

      }

      Console.WriteLine() ;
      return ;
    }

    static void Main( string[] args )
    {
      List<int> list1 = new List<int>( new []{ 1 ,             } ) ;
      List<int> list2 = new List<int>( new []{ 1 , 2 ,         } ) ;
      List<int> list3 = new List<int>( new []{ 1 , 2 , 3 ,     } ) ;
      List<int> list4 = new List<int>( new []{ 1 , 2 , 3 , 4 , } ) ;

      Console.WriteLine( "List 1:" ) ; WalkList( list1 ) ;
      Console.WriteLine( "List 2:" ) ; WalkList( list2 ) ;
      Console.WriteLine( "List 3:" ) ; WalkList( list3 ) ;
      Console.WriteLine( "List 4:" ) ; WalkList( list4 ) ;

      return ;
    }

  }
}

取決於你對“花式”的定義。 這可能符合:

if (myList.Count > 0)
{
    myList.Take(myList.Count - 1)).ForEach(myString => doSomething(myString));
    doSomethingElse(myList.Last());
}

對我來說,這似乎接近你正在尋找的東西。 請注意,它不是超高性能,但它很短且可讀性強,至少在我看來。 你也可以這樣寫:

if (myList.Count > 0)
{
    foreach (string myString in myList.Take(myList.Count - 1))
    {
         doSomething(myString);
    }

    doSomethingElse(myList.Last());
}

這是另一種選擇,我認為這是最明顯的,但它可能是最快的方法:

if (myList.Count > 0)
{
    for (int i = 0; i < myList.Count - 1; i++)
    {
        doSomething(myList[i]);
    }

    doSomethingElse(myList.Count - 1);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM