在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++;
}
当前回答
我不确定你试图用基于问题的索引信息做什么。然而,在c#中,你通常可以使用IEnumerable。Select方法从您想要的任何内容中获取索引。例如,我可以使用类似这样的方法来判断一个值是奇数还是偶数。
string[] names = { "one", "two", "three" };
var oddOrEvenByName = names
.Select((name, index) => new KeyValuePair<string, int>(name, index % 2))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
这将根据列表中的项是奇数(1)还是偶数(0)的名称为您提供一个字典。
其他回答
它只适用于List而不是任何IEnumerable,但在LINQ中有这样的:
IList<Object> collection = new List<Object> {
new Object(),
new Object(),
new Object(),
};
foreach (Object o in collection)
{
Console.WriteLine(collection.IndexOf(o));
}
Console.ReadLine();
@Jonathan我没有说这是一个很好的答案,我只是说这只是表明,他要求的事情是可以做到的:)
@Graphain我不期望它会很快-我不完全确定它是如何工作的,它可以重复整个列表每次找到一个匹配的对象,这将是一个非常大量的比较。
也就是说,List可能保留每个对象的索引和计数。
乔纳森似乎有更好的主意,能详细说说吗?
不过,最好只是记录一下你在foreach中所做的事情,这样更简单,适应性更强。
我就是这么做的,这很简单,但如果你在循环body obj中做了很多。价值,它很快就会过时。
foreach(var obj in collection.Select((item, index) => new { Index = index, Value = item }) {
string foo = string.Format("Something[{0}] = {1}", obj.Index, obj.Value);
...
}
我不相信有一种方法可以获得foreach循环当前迭代的值。数数自己,似乎是最好的办法。
我能问一下,你为什么想知道?
看起来你最有可能做以下三件事中的一件:
1)从集合中获取对象,但在这种情况下,您已经拥有它。
2)为后期处理计算对象…集合有一个可以使用的Count属性。
3)根据对象在循环中的顺序设置它的属性…尽管您可以在将对象添加到集合时轻松地进行设置。
像这样的怎么样?注意,如果myEnumerable为空,myDelimitedString可能为空。
IEnumerator enumerator = myEnumerable.GetEnumerator();
string myDelimitedString;
string current = null;
if( enumerator.MoveNext() )
current = (string)enumerator.Current;
while( null != current)
{
current = (string)enumerator.Current; }
myDelimitedString += current;
if( enumerator.MoveNext() )
myDelimitedString += DELIMITER;
else
break;
}
你可以这样写你的循环:
var s = "ABCDEFG";
foreach (var item in s.GetEnumeratorWithIndex())
{
System.Console.WriteLine("Character: {0}, Position: {1}", item.Value, item.Index);
}
之后添加如下结构和扩展方法。
结构和扩展方法封装了Enumerable。选择功能。
public struct ValueWithIndex<T>
{
public readonly T Value;
public readonly int Index;
public ValueWithIndex(T value, int index)
{
this.Value = value;
this.Index = index;
}
public static ValueWithIndex<T> Create(T value, int index)
{
return new ValueWithIndex<T>(value, index);
}
}
public static class ExtensionMethods
{
public static IEnumerable<ValueWithIndex<T>> GetEnumeratorWithIndex<T>(this IEnumerable<T> enumerable)
{
return enumerable.Select(ValueWithIndex<T>.Create);
}
}