在c#中是否有一些我没有遇到过的罕见的语言构造(比如我最近学过的一些,一些在Stack Overflow上)来获得表示foreach循环的当前迭代的值?
例如,我目前根据具体情况做这样的事情:
int i = 0;
foreach (Object o in collection)
{
// ...
i++;
}
在c#中是否有一些我没有遇到过的罕见的语言构造(比如我最近学过的一些,一些在Stack Overflow上)来获得表示foreach循环的当前迭代的值?
例如,我目前根据具体情况做这样的事情:
int i = 0;
foreach (Object o in collection)
{
// ...
i++;
}
当前回答
int index;
foreach (Object o in collection)
{
index = collection.indexOf(o);
}
这适用于支持IList的集合。
其他回答
c# 7最终为我们提供了一种优雅的方式:
static class Extensions
{
public static IEnumerable<(int, T)> Enumerate<T>(
this IEnumerable<T> input,
int start = 0
)
{
int i = start;
foreach (var t in input)
{
yield return (i++, t);
}
}
}
class Program
{
static void Main(string[] args)
{
var s = new string[]
{
"Alpha",
"Bravo",
"Charlie",
"Delta"
};
foreach (var (i, t) in s.Enumerate())
{
Console.WriteLine($"{i}: {t}");
}
}
}
这并没有回答您的具体问题,但它确实为您的问题提供了一个解决方案:使用for循环来遍历对象集合。然后您将得到您正在处理的当前索引。
// Untested
for (int i = 0; i < collection.Count; i++)
{
Console.WriteLine("My index is " + i);
}
除非你的集合可以通过某种方法返回对象的索引,否则唯一的方法就是使用像你的例子中那样的计数器。
然而,当使用索引时,唯一合理的答案是使用for循环。其他任何事情都会带来代码的复杂性,更不用说时间和空间的复杂性了。
这样你就可以使用LINQ来使用索引和值:
ListValues.Select((x, i) => new { Value = x, Index = i }).ToList().ForEach(element =>
{
// element.Index
// element.Value
});
使用@FlySwat的答案,我想出了这个解决方案:
//var list = new List<int> { 1, 2, 3, 4, 5, 6 }; // Your sample collection
var listEnumerator = list.GetEnumerator(); // Get enumerator
for (var i = 0; listEnumerator.MoveNext() == true; i++)
{
int currentItem = listEnumerator.Current; // Get current item.
//Console.WriteLine("At index {0}, item is {1}", i, currentItem); // Do as you wish with i and currentItem
}
你使用GetEnumerator来获取枚举器,然后使用for循环来进行循环。然而,诀窍是使循环的条件listEnumerator.MoveNext() == true。
由于枚举器的MoveNext方法如果存在下一个元素并且可以访问它,则返回true,因此循环条件使循环在耗尽要遍历的元素时停止。