在C#字典上迭代';s带有索引的键
本文关键字:索引 字典 迭代 | 更新日期: 2023-09-27 18:11:55
如何在维护键的索引的同时迭代Dictionary的键。我所做的是将一个foreach
-循环与一个局部变量i
合并,该变量在循环的每一轮中都会增加一。
这是我的工作代码:
public IterateOverMyDict()
{
int i=-1;
foreach (string key in myDict.Keys)
{
i++;
Console.Write(i.ToString() + " : " + key);
}
}
然而,使用局部变量i
似乎技术含量很低。我想知道是否有一种方法可以让我不必使用"额外"变量?不是说这是一种糟糕的方式,但有更好的方式吗?
没有"键的索引"这样的概念。您应该始终将Dictionary<TKey, TValue>
视为具有不可预测的顺序,其中您在迭代它时所得到的顺序可能会发生变化。(因此,理论上,你可以添加一个新条目,下次迭代时条目的顺序可能完全不同。理论上,如果不更改数据,这甚至可能发生,但在正常实现中不太可能。(
如果真的想得到这次碰巧观察到的数字索引,你可以使用:
foreach (var x in dictionary.Select((Entry, Index) => new { Entry, Index }))
{
Console.WriteLine("{0}: {1} = {2}", x.Index, x.Entry.Key, x.Entry.Value);
}
但要注意,这是一个相当误导性的展示,因为它暗示了一种内在的秩序。
来自文件:
为了枚举的目的,字典中的每个项都被视为代表一个值及其键的
KeyValuePair<TKey, TValue>
结构。返回项目的顺序未定义。
编辑:如果你不喜欢这里的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));
}
}
那么你的循环将是:
foreach (var x in dictionary.WithIndex())
{
Console.WriteLine("{0}: {1} = {2}", x.Index, x.Value.Key, x.Value.Value);
}
从技术上讲,关键是Dictionary<TKey, TValue>
中的索引。您不能保证以任何特定的顺序获得项目,因此实际上没有要应用的数字索引。
不是。请注意,字典中的关键字在逻辑上不是"有序的"。他们没有索引。从字典的角度来看,没有第一个或最后一个关键字。您可以自己跟踪这是否是枚举器返回的第一个键,就像您正在做的那样,但Dictionary没有"给我第五个键"的概念,所以您不能像对列表或数组那样对索引器使用for
循环。
字典并不完全是列表、数组或向量。他们将这些构造向前推进了一步。密钥可以是索引:
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]);
}
在这一点上,您可能错过了字典的大部分优点(它类似于枚举,具有快速排序键值的优点(,并像列表一样使用它。
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);
有专业人士&这两种方法的缺点取决于你要做的事情。