C#中foreach循环中的计数器

Jav*_*ram 43 c# foreach counter

foreach的工作: 据我所知,

foreach是一个循环,它逐个遍历集合或数组,从0索引开始直到集合的最后一项.

所以,如果我在数组中有n个项目.

foreach (var item in arr)
{

}  
Run Code Online (Sandbox Code Playgroud)

然后,在第一次迭代中,item = arr [0];
然后,在第2, item = arr [1];
.
.
.
在last(nth), item = arr [n-1];

结论:从工作开始,它似乎在每次迭代时都知道从数组中取出哪个值,或者它知道要从数组中获取的项的索引.

现在我的问题是:如何在不使用新变量的情况下获取项目的索引?

foreach (string item in mylist)
{
   if (item == "myitem")
   {
       // get index of item
       break;
   }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 85

这取决于你的意思"它".迭代器知道它到达了什么索引,是 - 在一个List<T>或一个数组的情况下.但内部没有一般指数IEnumerator<T>.它是否在索引集合上进行迭代取决于实现.大量集合不支持直接索引.

(事实上,foreach并不总是使用在所有的迭代器.如果集合的编译时间类型是数组,编译器将在其上使用迭代array[0],array[1]等等.同样的收集可以有一个被调用的方法GetEnumerator(),它返回一个带有类型适当的成员,但没有任何实施IEnumerable/ IEnumerator在视线内.)

维护索引的选项:

  • 使用for循环
  • 使用单独的变量
  • 使用投影将每个项目投影到索引/值对,例如

     foreach (var x in list.Select((value, index) => new { value, index }))
     {
         // Use x.value and x.index in here
     }
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用我的SmartEnumerable类有点像以前的选项

除了第一个选项外,其他所有选项都可以使用,无论该集合是否自然编入索引.

  • 你的投影方法优雅而简单,我会捏的! (2认同)

Yod*_*ber 18

for而不是foreach.foreach不公开其内部工作,它枚举任何东西IEnumerable(根本不必有索引).

for (int i=0; i<arr.Length; i++)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

此外,如果你要做的是找到列表中特定项目的索引,则不必自己迭代它.请Array.IndexOf(item)改用.


Ode*_*ded 12

你的理解foreach是不完整的.

它适用于任何暴露IEnumerable(或实现GetEnumerable方法)的类型,并使用返回IEnumerator来迭代集合中的项目.

这是如何Enumerator(使用索引,yield语句或魔术)是一个实现细节.

为了达到你想要的效果,你应该使用一个for循环:

for (int i = 0; i < mylist.Count; i++)
{
}
Run Code Online (Sandbox Code Playgroud)

注意:

获取列表中的项目数量会略有不同,具体取决于列表的类型

For Collections: Use Count   [property]
For Arrays:      Use Length  [property]
For IEnumerable: Use Count() [Linq method]
Run Code Online (Sandbox Code Playgroud)


Blu*_*doo 8

或者更简单,如果你不想使用很多linq并且由于某种原因不想使用for循环.

int i = 0;
foreach(var x in arr)
{
   //Do some stuff
   i++;
}
Run Code Online (Sandbox Code Playgroud)