28

如何foreach在 C# 的循环中获取当前元素的键?

例如:

PHP

foreach ($array as $key => $value)
{
    echo("$value is assigned to key: $key");
}

我在 C# 中尝试做的事情:

int[] values = { 5, 14, 29, 49, 99, 150, 999 };

foreach (int val in values)
{
    if(search <= val && !stop)
    {
         // Set key to a variable
    }
}
4

9 回答 9

24

Grauenwolf 的方式是使用数组执行此操作的最直接和最高效的方式:

要么使用 for 循环,要么创建一个在每次传递时递增的临时变量。

这当然看起来像这样:

int[] values = { 5, 14, 29, 49, 99, 150, 999 };

for (int key = 0; key < values.Length; ++key)
  if (search <= values[key] && !stop)
  {
    // set key to a variable
  }

使用 .NET 3.5,您也可以采用更实用的方法,但它在站点上有点冗长,并且可能依赖于几个支持函数访问IEnumerable 中的元素。如果这就是你所需要的一切,那就有点矫枉过正了,但如果你倾向于做大量的收集处理,那就很方便了。

于 2008-09-12T22:34:50.860 回答
23

如果您想获得关键(阅读:索引),那么您必须使用 for 循环。如果你真的想要一个包含键/值的集合,那么我会考虑使用 HashTable 或 Dictionary (如果你想使用泛型)。

Dictionary<int, string> items = new  Dictionary<int, string>();

foreach (int key in items.Keys)
{
  Console.WriteLine("Key: {0} has value: {1}", key, items[key]);
}

希望有帮助,泰勒

于 2008-09-12T21:58:53.957 回答
9

使用 DictionaryEntry 和 KeyValuePair:

基于
MSDN

IDictionary<string,string> openWith = new Dictionary<string,string>()
{
   { "txt", "notepad.exe" }
   { "bmp", "paint.exe" }
   { "rtf", "wordpad.exe" }
};

foreach (DictionaryEntry de in openWith)
{
    Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}

// also

foreach (KeyValuePair<string,string> de in openWith)
{
    Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}

相关的 SO 问题:KeyValuePair VS DictionaryEntry

于 2011-09-09T19:15:03.133 回答
4

唉,没有内置的方法可以做到这一点。要么使用 for 循环,要么创建一个在每次传递时递增的临时变量。

于 2008-09-12T21:48:40.923 回答
3

我在这个问题的另一个版本中回答了这个问题:

Foreach 用于迭代实现 IEnumerable 的集合。它通过在集合上调用 GetEnumerator 来完成此操作,这将返回一个 Enumerator。

这个 Enumerator 有一个方法和一个属性:

* MoveNext()
* Current

Current 返回 Enumerator 当前所在的对象,MoveNext 将 Current 更新为下一个对象。

显然,索引的概念与枚举的概念是陌生的,无法做到。

因此,大多数集合都可以使用索引器和 for 循环结构进行遍历。

与使用局部变量跟踪索引相比,我更喜欢在这种情况下使用 for 循环。

您如何获得 foreach 循环的当前迭代的索引?

于 2008-09-12T22:38:31.897 回答
2

实际上,如果要遍历数组,则应该使用经典的 for (;;) 循环。但是您使用 PHP 代码实现的类似功能可以在 C# 中实现,例如使用 Dictionary:

Dictionary<int, int> values = new Dictionary<int, int>();
values[0] = 5;
values[1] = 14;
values[2] = 29;
values[3] = 49;
// whatever...

foreach (int key in values.Keys)
{
    Console.WriteLine("{0} is assigned to key: {1}", values[key], key);
}
于 2008-09-12T21:59:59.883 回答
0

这是我刚刚为这个问题提出的解决方案

原始代码:

int index=0;
foreach (var item in enumerable)
{
    blah(item, index); // some code that depends on the index
    index++;
}

更新代码

enumerable.ForEach((item, index) => blah(item, index));

扩展方法:

    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
    {
        var unit = new Unit(); // unit is a new type from the reactive framework (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx) to represent a void, since in C# you can't return a void
        enumerable.Select((item, i) => 
            {
                action(item, i);
                return unit;
            }).ToList();

        return pSource;
    }
于 2009-12-31T05:29:17.923 回答
0

您可以使用扩展方法自己实现此功能。例如,这是一个适用于列表的扩展方法 KeyValuePairs 的实现:

public struct IndexValue<T> {
    public int Index {get; private set;}
    public T Value {get; private set;}
    public IndexValue(int index, T value) : this() {
        this.Index = index;
        this.Value = value;
    }
}

public static class EnumExtension
{
    public static IEnumerable<IndexValue<T>> KeyValuePairs<T>(this IList<T> list) {
        for (int i = 0; i < list.Count; i++)
            yield return new IndexValue<T>(i, list[i]);
    }
}
于 2009-12-31T06:12:08.447 回答
-10

myKey = Array.IndexOf(values, val);

于 2008-09-12T21:53:34.420 回答