是否有C#相当于Python enumerate()
和Ruby each_with_index
?
我保留了这个扩展方法:
public static void Each(this IEnumerable ie, Action action) { var i = 0; foreach (var e in ie) action(e, i++); }
并像这样使用它:
var strings = new List(); strings.Each((str, n) => { // hooray });
或者允许break
类似行为:
public static bool Each(this IEnumerable ie, Func action) { int i = 0; foreach (T e in ie) if (!action(e, i++)) return false; return true; } var strings = new List () { "a", "b", "c" }; bool iteratedAll = strings.Each ((str, n)) => { if (str == "b") return false; return true; });
您可以执行以下操作
foreach (var it in someCollection.Select((x, i) => new { Value = x, Index = i }) ) { if (it.Index > SomeNumber) // }
这将为collect中的每个条目创建一个匿名类型值.它将有两个属性
值:具有集合中的原始值
索引:具有集合内的索引
C#foreach没有内置索引.你需要在foreach循环之外添加一个整数,并且每次都增加它.
int i = -1; foreach (Widget w in widgets) { i++; // do something }
或者,您可以使用标准for循环,如下所示:
for (int i = 0; i < widgets.Length; i++) { w = widgets[i]; // do something }
我喜欢能够使用foreach,所以我做了一个扩展方法和一个结构:
public struct EnumeratedInstance{ public long cnt; public T item; } public static IEnumerable > Enumerate (this IEnumerable collection) { long counter = 0; foreach (var item in collection) { yield return new EnumeratedInstance { cnt = counter, item = item }; counter++; } }
和一个使用示例:
foreach (var ii in new string[] { "a", "b", "c" }.Enumerate()) { Console.WriteLine(ii.item + ii.cnt); }
一个好处是,如果你习惯了Python语法,你仍然可以使用它:
foreach (var ii in Enumerate(new string[] { "a", "b", "c" }))
除了已经给出的LINQ答案之外,我还有一个"SmartEnumerable"类,它允许您获取索引和"第一个/最后一个" - .它在语法方面有点难看,但你可能会发现它很有用.
我们可以使用非泛型类型中的静态方法来改进类型推断,并且隐式类型也会有所帮助.
我的解决方案涉及一个简单的Pair类,我为通用实用程序创建,它在操作上与框架类KeyValuePair基本相同.然后我为IEnumerable创建了一个名为Ordinate的扩展函数(来自集合论术语" 序数 ").
这些函数将为包含索引的Pair对象和项本身返回每个项目.
public static IEnumerable> Ordinate (this IEnumerable lhs) { return lhs.Ordinate(0); } public static IEnumerable > Ordinate (this IEnumerable lhs, Int32 initial) { Int32 index = initial - 1; return lhs.Select(x => new Pair (++index, x)); }