C# 带索引的 foreach

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/521687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 06:37:39  来源:igfitidea点击:

foreach with index

c#foreach

提问by Ken

Is there a C# equivalent of Python's enumerate()and Ruby's each_with_index?

是否有等效于 Pythonenumerate()和 Ruby 的C# each_with_index

回答by David Morton

The C# foreach doesn't have a built in index. You'll need to add an integer outside the foreach loop and increment it each time.

C# foreach 没有内置索引。您需要在 foreach 循环外添加一个整数并每次递增。

int i = -1;
foreach (Widget w in widgets)
{
   i++;
   // do something
}

Alternatively, you could use a standard for loop as follows:

或者,您可以使用标准 for 循环,如下所示:

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

回答by VBNight

It depends on the class you are using.

这取决于您使用的类。

Dictionary<(Of <(TKey, TValue>)>) Class For Example Support This

Dictionary<(Of <(TKey, TValue>)>) 类例如支持这个

The Dictionary<(Of <(TKey, TValue>)>) generic class provides a mapping from a set of keys to a set of values.

Dictionary<(Of <(TKey, TValue>)>) 泛型类提供从一组键到一组值的映射。

For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair<(Of <(TKey, TValue>)>) structure representing a value and its key. The order in which the items are returned is undefined.

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

foreach (KeyValuePair kvp in myDictionary) {...}

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

回答by JaredPar

You can do the following

您可以执行以下操作

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

This will create an anonymous type value for every entry in the collection. It will have two properties

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

  • Value: with the original value in the collection
  • Index: with the index within the collection
  • Value: 具有收藏中的原始价值
  • Index: 带有集合中的索引

回答by Jon Skeet

Aside from the LINQ answers already given, I have a "SmartEnumerable"class which allows you to get the index and the "first/last"-ness. It's a bit ugly in terms of syntax, but you may find it useful.

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

We can probably improve the type inference using a static method in a nongeneric type, and implicit typing will help too.

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

回答by Chris Ammerman

My solution involves a simple Pair class I created for general utility, and which is operationally essentially the same as the framework class KeyValuePair. Then I created a couple extension functions for IEnumerable called Ordinate (from the set theory term "ordinal").

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

These functions will return for each item a Pair object containing the index, and the item itself.

这些函数将为每个项目返回一个包含索引和项目本身的 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));
}

回答by Darryl Braaten

No, there is not.

不,那里没有。

As other people have shown, there are ways to simulate Ruby's behavior. But it is possible to have a type that implements IEnumerablethat does not expose an index.

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

回答by Dan

I keep this extension method around for this:

为此,我保留了这个扩展方法:

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

And use it like so:

并像这样使用它:

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

Or to allow for break-like behaviour:

或者允许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;
});

回答by Pz.

I just figured out interesting solution:

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

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);
    }
}

Usage:

用法:

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);
}

回答by vonWippersnap

This is your collection

这是你的收藏

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

Make a range of indexes for this collection

为这个集合建立一系列索引

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

Use the range to iterate with index

使用范围迭代索引

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

回答by Daniel K

I like being able to use foreach, so I made an extension method and a structure:

我喜欢能够使用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++;
    }
}

and an example use:

和一个示例使用:

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

One nice thing is that if you are used to the Python syntax, you can still use it:

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

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