Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用索引迭代C字典的键?_C#_Loops_Dictionary_Iteration - Fatal编程技术网

C# 用索引迭代C字典的键?

C# 用索引迭代C字典的键?,c#,loops,dictionary,iteration,C#,Loops,Dictionary,Iteration,如何在维护键的索引的同时迭代字典的键。 我所做的是将一个foreach循环与一个局部变量I合并,该局部变量I在循环的每一轮中递增一 以下是我的代码: public IterateOverMyDict() { int i=-1; foreach (string key in myDict.Keys) { i++; Console.Write(i.ToString() + " : " + key); } } 然而,使用局部变量i似乎技

如何在维护键的索引的同时迭代字典的键。 我所做的是将一个foreach循环与一个局部变量I合并,该局部变量I在循环的每一轮中递增一

以下是我的代码:

public IterateOverMyDict()
{
    int i=-1;
    foreach (string key in myDict.Keys)
    {
        i++;
        Console.Write(i.ToString() + " : " + key);
    }
}
然而,使用局部变量i似乎技术含量很低。 我想知道是否有一种方法不必使用额外的变量?
不是说这是一种不好的方法,但是有更好的方法吗?

没有键的索引这样的概念。您应该始终将字典视为具有不可预测的顺序—在这种情况下,迭代字典时碰巧得到的顺序可能会发生变化。所以从理论上讲,您可以添加一个新条目,下次迭代时,条目的顺序可能会完全不同。理论上,这甚至可以在不更改数据的情况下发生,但在正常实现中不太可能发生

如果你真的想得到你这次碰巧观察到的数值索引,你可以使用:

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结构。返回项目的顺序未定义

编辑:如果您不喜欢此处的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));
    }
}

从技术上讲,关键是字典中的索引。您不能保证按任何特定顺序获取项目,因此实际上没有要应用的数字索引。

不一定。请注意,字典中的键不是按逻辑顺序排列的。他们没有索引。从字典的角度来看,没有第一个或最后一个键。您可以自己跟踪这是否是枚举器返回的第一个键,就像您正在做的那样,但是字典没有给我第五个键的概念,因此您不能像使用列表或数组那样使用带有索引器的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]);
}

在这一点上,您可能错过了字典的大部分好处,它类似于枚举,具有对键值进行快速排序并将其用作列表的好处。

SelectEntry,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);

这两种方法都有优点和缺点,具体取决于您要做什么。

顺序对我来说并不重要,我现在不需要TValue,我只需要打印前面有某种索引的键,这样用户就可以键入select 1,然后它将选择索引为1的键。在打印版本中,前面有1的键,也就是说。@MarkusMeskanen:那么,在维护键的索引时,您为什么要问一个问题?无论如何,我向您展示的LINQ查询应该会有所帮助。对于没有将英语作为我的母语表示歉意,我不知道如果这还不够清楚,我该怎么问它。:/然而,这就是为什么我给你我正在使用atm的代码,作为一个例子来说明我根本没有使用TValue,我只是在它前面打印键和一个int。恕我直言,LINQ看起来很糟糕,我宁愿使用我自己的解决方案,谢谢你的回答tho:@MarkusMeskanen:只要解释一下你知道订单不稳定,以及你为什么想要这样一个误导性的显示,就会有所帮助。我看不出LINQ有什么问题——考虑到您需要从某个地方获得额外的值,您希望有什么其他可能的解决方案?你可以写一个方法来索引任何序列,但是通过一个自定义结构,我想…我不需要按任何特定的顺序使用它们,我只需要遍历键并用从1到键的整数打印它们。在它们前面计数这回答了你的问题吗?
var x = dictionary.ToList();
for (int y=0; y<x.Count; y++) Console.WriteLine(y + " = " + x[y].Key);