在“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使用 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您可以使用扩展方法自己实现此功能。例如,这是一个在列表上工作的扩展方法 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”循环中获取数组键的主要内容,如果未能解决你的问题,请参考以下文章