关于c#:foreach with index

foreach with index

本问题已经有最佳答案,请猛点这里访问。

有没有与python的enumerate()和ruby的each_with_index等价的c?


我保留这个扩展方法:

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

像这样使用它:

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

或者考虑到break样的行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
2
3
4
foreach (var it in someCollection.Select((x, i) => new { Value = x, Index = i }) )
{
   if (it.Index > SomeNumber) //      
}

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

  • 值:集合中的原始值
  • 索引:包含集合中的索引

  • C语言的前缀没有内置索引。您需要在FACH循环之外添加一个整数,并每次增加它。

    1
    2
    3
    4
    5
    6
    int i = -1;
    foreach (Widget w in widgets)
    {
       i++;
       // do something
    }

    或者,您可以使用循环的标准如下:

    1
    2
    3
    4
    5
    for (int i = 0; i < widgets.Length; i++)
    {
       w = widgets[i];
       // do something
    }


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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++;
        }
    }

    示例用法:

    1
    2
    3
    4
    foreach (var ii in new string[] {"a","b","c" }.Enumerate())
    {
        Console.WriteLine(ii.item + ii.cnt);
    }

    一个好处是,如果您习惯了Python语法,您仍然可以使用它:

    1
    foreach (var ii in Enumerate(new string[] {"a","b","c" }))


    除了已经给出的LINQ答案,我还有一个"智能可计算"类,它允许您获取索引和"第一/最后一个"。它的语法有点难看,但你可能会发现它很有用。

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


    我的解决方案涉及一个我为通用工具创建的简单pair类,它在操作上与框架类keyValuePair基本相同。然后我为IEnumerable创建了两个扩展函数,称为坐标(从集合理论术语"序数")。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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));
    }


    不,没有。

    正如其他人所展示的,有一些方法可以模拟Ruby的行为。但有可能具有实现不公开索引的IEnumerable的类型。


    这是你的收藏

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

    为此集合生成一系列索引

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

    使用范围与索引迭代

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

    我刚刚想出了一个有趣的解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    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);
        }
    }

    用途:

    1
    2
    3
    4
    5
    6
    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);
    }


    这取决于你正在使用的班级。

    Dictionary<(of<(tkey,tvalue>)>)类,例如支持

    dictionary<(of<(tkey,tvalue>)>)泛型类提供从一组键到一组值的映射。

    为了进行枚举,字典中的每个项都被视为keyValuePair<(of<(tkey,tvalue>)>)结构,表示一个值及其键。返回项目的顺序未定义。

    foreach(myDictionary中的keyValuePair kvp)…