如何知道循环的最后一次迭代?

8

有没有一种高级的方法可以知道您是否在列表的最后一个循环中,而不使用计数器

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?
}

1
你试图对最后一个元素做什么? 你想建立一个句子并在末尾添加标点吗?如果是这样,你可以尝试string.Join(" ", myList.ToArray()) + "." - hunter
在页面底部找到了一个解决方案,希望对你有所帮助。 - hunter
9个回答

10

不行,你必须使用常规的 for(int i=0; i<myList.Length; i++) { ... } 循环来做那件事。


1
谢谢,这是我的备选方案,但我想先确认一下我没有漏掉什么。 - Terco

4
使用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循环。


4
我有两种方法可以做到这一点。首先,使用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();

    ...
}

1

嗯...没有办法知道。这并不像你想象的那样容易。列表数据结构只是一种将项目依次排序的方法。但是,您无法使用foreach结构仅凭一个项目来判断是否为最后一个项目。最好使用具有count属性的结构以了解是否达到了最后(或上一个)项目。

var length = list.Count;

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

希望能有所帮助。


1

没有一种高效的方法来完成这个任务。

只需使用 for 循环和索引。它运行起来更快。


0

“花哨”的方法是保持1个前瞻元素,但你到底为什么要这样做呢?只需保持计数即可。以下是“花哨”的方法。没有计数器,也没有检查计数属性。它只使用了一个枚举器:

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 ;
    }

  }
}

0

没有,如果你想使用foreach,你必须使用计数器。


0

使用 for 操作符替代 foreach


0

这取决于你对“炫酷”的定义。这个可能符合要求:

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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接