在“foreach”循环中获取数组键

Posted

技术标签:

【中文标题】在“foreach”循环中获取数组键【英文标题】:Getting the array key in a 'foreach' loop 【发布时间】:2010-09-08 18:29:31 【问题描述】:

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

例如:

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
    

【问题讨论】:

【参考方案1】:

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

要么使用 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,您也可以采用更实用的方法,但它在站点上有点冗长,并且可能依赖于 support functions 的一对 visiting IEnumerable 中的元素。如果这就是你所需要的,那就有点矫枉过正了,但如果你倾向于做大量的收集处理,那就很方便了。

【讨论】:

"或创建一个在每次传递时递增的临时变量" 据我所知,不能保证 foreach 会以升序(或降序)顺序,只是它会在恰好一次处停止每个元素,因此如果您使用外部值,您的解决方案可能 - 也可能不是基于实现的有效。通常它会给你想要的结果,但即一个常见的优化是按降序解析数组(它比每个周期的升序需要更少的机器指令)。 我认为这取决于您迭代的可枚举类型。如果它是一个数组,我认为可以保证顺序。【参考方案2】:

如果您想获得关键(阅读:索引),那么您必须使用 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]);

希望对您有所帮助, 泰勒

【讨论】:

执行 foreach(KeyValuePair pair in items) 然后引用 pair.Key 和 pair.Value,而不是在每次迭代中进行查找会更高效。跨度> 【参考方案3】:

使用 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);

Releated SO question: KeyValuePair VS DictionaryEntry

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

Foreach 用于迭代 实现的集合 可数的。它通过调用 集合上的 GetEnumerator,其中 将返回一个枚举器。

这个枚举器有一个方法和一个 属性:

* MoveNext()
* Current

Current 返回的对象 枚举器当前处于打开状态,MoveNext 将 Current 更新为下一个对象。

显然,索引的概念是 与枚举的概念无关, 并且无法完成。

因此,大多数集合都是 能够使用索引器遍历 和 for 循环构造。

我非常喜欢使用 for 循环 这种情况相比跟踪 带有局部变量的索引。

How do you get the index of the current iteration of a foreach loop?

【讨论】:

【参考方案6】:

实际上,如果你想遍历一个数组,你应该使用经典的 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);

【讨论】:

执行 foreach(KeyValuePair pair in values) 然后引用 pair.Key 和 pair.Value,而不是在每次迭代中进行查找会更高效。跨度> 【参考方案7】:

您可以使用扩展方法自己实现此功能。例如,这是一个在列表上工作的扩展方法 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]);
    

【讨论】:

【参考方案8】:

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

原始代码:

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;
    

【讨论】:

【参考方案9】:

myKey = Array.IndexOf(values, val);

【讨论】:

这不是一个好主意。 Array.IndexOf 基本上是一个 O(n) 的更坏情况的搜索。这样做 n 次,你的总的最坏情况会变成 O(n^2)。用外行的话来说,一个包含 100 个项目的数组可能需要进行多达 10000 次比较。 抛开效率不谈,如果数组中有重复的项目,您将获得第一个的索引,不一定是您所在的那个。考虑一个 5, 14, 5, 29, ... 的数组。当 'val' 为 5 时,即使你在第三个元素上,你也总是会得到零。

以上是关于在“foreach”循环中获取数组键的主要内容,如果未能解决你的问题,请参考以下文章

如何从foreach循环中的匹配值获取下一个值

PHP中如何使用foreach结构遍历数组?

PHP数组在foreach()中获取下一个键/值[重复]

foreach的基本语法

php foreach怎样获取当前的循环次数

如何使用php在foreach循环中获取多维数组的键? [复制]