foreach with index

时间:2009-02-06 19:01:32

标签: c# foreach

是否有C#相当于Python的enumerate()和Ruby的each_with_index

10 个答案:

答案 0 :(得分:253)

我保留了这种扩展方法:

public static void Each<T>(this IEnumerable<T> ie, Action<T, int> action)
{
    var i = 0;
    foreach (var e in ie) action(e, i++);
}

并像这样使用它:

var strings = new List<string>();
strings.Each((str, n) =>
{
    // hooray
});

或允许break - 类似行为:

public static bool Each<T>(this IEnumerable<T> ie, Func<T, int, bool> action)
{
    int i = 0;
    foreach (T e in ie) if (!action(e, i++)) return false;
    return true;
}

var strings = new List<string>() { "a", "b", "c" };

bool iteratedAll = strings.Each ((str, n)) =>
{
    if (str == "b") return false;
    return true;
});

答案 1 :(得分:194)

您可以执行以下操作

foreach (var it in someCollection.Select((x, i) => new { Value = x, Index = i }) )
{
   if (it.Index > SomeNumber) //      
}

这将为collect中的每个条目创建一个匿名类型值。它将有两个属性

  1. 值:使用集合中的原始值
  2. 索引:集合中的索引

答案 2 :(得分:56)

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
}

答案 3 :(得分:15)

除了已经给出的LINQ答案之外,我还有一个"SmartEnumerable"类,它允许您获取索引和“第一个/最后一个” - 。它在语法方面有点难看,但你可能会发现它很有用。

我们可以使用非泛型类型中的静态方法改进类型推断,而隐式类型也会有所帮助。

答案 4 :(得分:15)

我喜欢能够使用foreach,所以我做了一个扩展方法和一个结构:

public struct EnumeratedInstance<T>
{
    public long cnt;
    public T item;
}

public static IEnumerable<EnumeratedInstance<T>> Enumerate<T>(this IEnumerable<T> collection)
{
    long counter = 0;
    foreach (var item in collection)
    {
        yield return new EnumeratedInstance<T>
        {
            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" }))

答案 5 :(得分:6)

我的解决方案涉及一个简单的Pair类,我为一般实用程序创建,它在操作上与框架类KeyValuePair基本相同。然后我为IEnumerable创建了一个名为Ordinate的扩展函数(来自集合论术语“ordinal”)。

这些函数将为包含索引的Pair对象和项本身返回每个项目。

public static IEnumerable<Pair<Int32, X>> Ordinate<X>(this IEnumerable<X> lhs)
{
    return lhs.Ordinate(0);
}

public static IEnumerable<Pair<Int32, X>> Ordinate<X>(this IEnumerable<X> lhs, Int32 initial)
{
    Int32 index = initial - 1;

    return lhs.Select(x => new Pair<Int32, X>(++index, x));
}

答案 6 :(得分:3)

不,没有。

正如其他人所表明的那样,有很多方法可以模拟Ruby的行为。但是有可能有一个实现IEnumerable但不公开索引的类型。

答案 7 :(得分:1)

我刚刚找到了有趣的解决方案:

public class DepthAware<T> : IEnumerable<T>
{
    private readonly IEnumerable<T> source;

    public DepthAware(IEnumerable<T> source)
    {
        this.source = source;
        this.Depth = 0;
    }

    public int Depth { get; private set; }

    private IEnumerable<T> GetItems()
    {
        foreach (var item in source)
        {
            yield return item;
            ++this.Depth;
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return GetItems().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

// Generic type leverage and extension invoking
public static class DepthAware
{
    public static DepthAware<T> AsDepthAware<T>(this IEnumerable<T> source)
    {
        return new DepthAware<T>(source);
    }

    public static DepthAware<T> New<T>(IEnumerable<T> source)
    {
        return new DepthAware<T>(source);
    }
}

用法:

var chars = new[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'}.AsDepthAware();

foreach (var item in chars)
{
    Console.WriteLine("Char: {0}, depth: {1}", item, chars.Depth);
}

答案 8 :(得分:1)

这是你的收藏

var values = new[] {6, 2, 8, 45, 9, 3, 0};

为此集合制作一系列索引

var indexes = Enumerable.Range(0, values.Length).ToList();

使用范围以索引

进行迭代
indexes.ForEach(i => values[i] += i);
indexes.ForEach(i => Console.Write("[{0}] = {1}", i, values[i]));

答案 9 :(得分:0)

这取决于您使用的课​​程。

Dictionary&lt;(Of&lt;(TKey,TValue&gt;)&gt;)Class for Example Support This

Dictionary&lt;(Of&lt;(TKey,TValue&gt;)&gt;)泛型类提供从一组键到一组值的映射。

出于枚举的目的,字典中的每个项目被视为表示值及其键的KeyValuePair&lt;(&lt;(TKey,TValue&gt;)&gt;)结构。返回项目的顺序未定义。

foreach(myDictionary中的KeyValuePair kvp){...}