使用索引迭代 C# 字典的键?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16341637/
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
Iterate over C# dictionary's keys with index?
提问by
How do I iterate over a Dictionary's keys while maintaining the index of the key.
What I've done is merge a foreach-loop with a local variable iwhich gets incremented by one for every round of the loop.
如何在保持键的索引的同时迭代字典的键。我所做的是将一个foreach-loop 与一个局部变量合并,该变量i在循环的每一轮都会增加 1。
Here's my code that works:
这是我的工作代码:
public IterateOverMyDict()
{
int i=-1;
foreach (string key in myDict.Keys)
{
i++;
Console.Write(i.ToString() + " : " + key);
}
}
However, it seems really low tech to use a local variable i.
I was wondering if there's a way where I don't have to use the "extra" variable?
Not saying this is a bad way, but is there a better one?
但是,使用局部变量似乎技术含量很低i。我想知道是否有一种方法可以不必使用“额外”变量?不是说这是一种不好的方法,但是有更好的方法吗?
采纳答案by Jon Skeet
There's no such concept as "the index of the key". You should always treat a Dictionary<TKey, TValue>as having an unpredictable order - where the order which you happento get when iterating over it may change. (So in theory, you could add one new entry, and the entries could be in a completely different order next time you iterated over them. In theory this could even happen withoutyou changing the data, but that's less likely in normal implementations.)
没有“键的索引”这样的概念。您应该始终将 aDictionary<TKey, TValue>视为具有不可预测的顺序 - 在迭代它时碰巧获得的顺序可能会改变。(因此,理论上,您可以添加一个新条目,并且下次您对其进行迭代时,这些条目的顺序可能完全不同。理论上,即使您不更改数据,也可能发生这种情况,但在正常实现中这种情况不太可能发生。)
If you reallywant to get the numeric index which you happened to observe this time, you could use:
如果你真的想得到你这次碰巧观察到的数字索引,你可以使用:
foreach (var x in dictionary.Select((Entry, Index) => new { Entry, Index }))
{
Console.WriteLine("{0}: {1} = {2}", x.Index, x.Entry.Key, x.Entry.Value);
}
... but be aware that that's a fairly misleading display, as it suggests an inherent ordering.
...但请注意,这是一个相当具有误导性的显示,因为它暗示了一种固有的顺序。
From the documentation:
从文档:
For purposes of enumeration, each item in the dictionary is treated as a
KeyValuePair<TKey, TValue>structure representing a value and its key. The order in which the items are returned is undefined.
出于枚举的目的,字典中的每一项都被视为
KeyValuePair<TKey, TValue>表示值及其键的结构。项目返回的顺序未定义。
EDIT: If you don't like the Selectcall here, you couldcreate your own extension method:
编辑:如果您不喜欢Select这里的调用,您可以创建自己的扩展方法:
public struct IndexedValue<T>
{
private readonly T value;
private readonly int index;
public T Value { get { return value; } }
public int Index { get { return index; } }
public IndexedValue(T value, int index)
{
this.value = value;
this.index = index;
}
}
public static class Extensions
{
public static IEnumerable<IndexedValue<T>> WithIndex<T>
(this IEnumerable<T> source)
{
return source.Select((value, index) => new IndexedValue<T>(value, index));
}
}
Then your loop would be:
那么你的循环将是:
foreach (var x in dictionary.WithIndex())
{
Console.WriteLine("{0}: {1} = {2}", x.Index, x.Value.Key, x.Value.Value);
}
回答by Justin Niessner
Technically, the key is the index in a Dictionary<TKey, TValue>. You're not guaranteed to get the items in any specific order, so there's really no numeric index to be applied.
从技术上讲,关键是 a 中的索引Dictionary<TKey, TValue>。您不能保证以任何特定顺序获取项目,因此实际上没有要应用的数字索引。
回答by Servy
Not really. Note that keys in a dictionary are not logically "ordered". They don't have an index. There is no first or last key, from the Dictionary's point of view. You can keep track on your own whether this is the first key returned by the enumerator, as you are doing, but the Dictionary has no concept of "give me the 5th key", so you couldn't use a forloop with an indexer as you could with a list or array.
并不真地。请注意,字典中的键在逻辑上不是“有序”的。他们没有索引。从字典的角度来看,没有第一个或最后一个键。您可以自己跟踪这是否是枚举器返回的第一个键,正如您所做的那样,但字典没有“给我第 5 个键”的概念,因此您不能使用for带有索引器的循环作为您可以使用列表或数组。
回答by amalgamate
Dictionaries are not exactly lists, arrays, or vectors. They take those constructs a step further. The key can be the index:
字典不完全是列表、数组或向量。他们将这些构造更进一步。键可以是索引:
Dictionary myDictionary<int, string> = new Dictionary<int, string>()
{
{0, "cat"},
{1, "dog"},
{2, "pig"},
{3, "horse"}
};
myDictionary[4] = "hat";
for int i = 0; i <5; i++){
Console.Writeline(myDictionary[i]);
}
At this point you are probably missing most of the benefits of a dictionary (which is similar to enumeration with the benefit of sorting quickly on key values), and using it like a list.
在这一点上,您可能错过了字典的大部分好处(它类似于枚举,具有对键值快速排序的好处),并且像列表一样使用它。
回答by ron
The Select((Entry, Index) => new { Entry, Index }) approach is probably best in the specific context of this question but, as an alternative, System.Linq.Enumerable now lets you convert a dictionary into a list. Something like this would work:
Select((Entry, Index) => new { Entry, Index }) 方法在这个问题的特定上下文中可能是最好的,但作为替代,System.Linq.Enumerable 现在允许您将字典转换为列表。像这样的事情会起作用:
var x = dictionary.ToList();
for (int y=0; y<x.Count; y++) Console.WriteLine(y + " = " + x[y].Key);
There are pros & cons to both approaches depending on what you're trying to do.
两种方法各有利弊,具体取决于您要做什么。

