通过数字索引访问Dictionary.Keys键

I'm using a Dictionary where the int is a count of the key.

现在,我需要访问字典中最后插入的Key,但我不知道它的名称。显而易见的尝试:

int LastCount = mydict[mydict.keys[mydict.keys.Count]];

不起作用,因为 Dictionary.Keys 没有实现[] -indexer。

I just wonder if there is any similar class? I thought about using a Stack, but that only stores a string. I could now create my own struct and then use a Stack, but I wonder if there is another alternative, essentially a Dictionary that implements an []-indexer on the Keys?

0
如果您将该变量加入,会发生什么?
额外 作者 Paul Prewett,

9 答案

我同意帕特里克答案的第二部分。即使在某些测试中似乎仍然保持插入顺序,但文档(以及字典和散列的正常行为)明确指出排序未指定。

取决于按键的顺序,您只是要求麻烦。加上你自己的簿记(就像帕特里克说的那样,只是最后一个添加键的单个变量)可以肯定。另外,不要被字典中的Last和Max等所有方法所吸引,因为这些方法可能与关键比较器有关(我不太确定)。

0
额外

我不知道这是否可行,因为我非常确定这些键不是按照它们添加的顺序存储的,但是您可以将KeysCollection转换为列表,然后获取列表中的最后一个键...但值得一看。

我唯一能想到的另一件事是将键存储在查找列表中,然后将键添加到列表中,然后将它们添加到字典中......这不是很好。

0
额外
@Juan:KeyCollection中没有.Last()方法
额外 作者 lomaxx,
我没有测试代码,但该方法记录在[MSDN] [1],也许它的另一个版本的框架? [1]: msdn.microsoft.com/en-us/library/bb908406。 ASPX
额外 作者 Juan,
2年后,但它可能有助于某人......看到我的回复下面的胡安的帖子。 Last()是一个扩展方法。
额外 作者 SuperOli,

你提到这个问题的方式让我相信词典中的int包含了该词典中的项目“位置”。从断言来看,这些键不是按照它们添加的顺序存储的,如果这是正确的,那将意味着keys.Count(或者.Count - 1,如果您使用的是基于零的)仍然应该始终是最后输入的密钥的数量?

If that's correct, is there any reason you can't instead use Dictionary so that you can use mydict[ mydict.Keys.Count ]?

0
额外

您可以使用 OrderedDictionary

表示键/值的集合   可通过密钥访问的配对   或索引。

0
额外
Erhm,在19个upvotes之后,没有人提到OrderedDictionary仍然不允许通过索引获得关键字?
额外 作者 Lazlo,
您可以使用带有 OrderedDictionary 的整数索引访问值,但不能使用 System.Collections.Generic.SortedDictionary 索引需要为TKEY的
额外 作者 Maxence,

你可以一直这样做:

string[] temp = new string[mydict.count];
mydict.Keys.CopyTo(temp, 0)
int LastCount = mydict[temp[mydict.count - 1]]

但我不会推荐它。不能保证最后插入的键将在数组的末尾。对于 MSDN上的的订购是未指定的,可能会更改。在我非常简短的测试中,它似乎是按照插入的顺序排列的,但是您最好是像使用堆栈一样进行适当的簿记工作 - 正如您所建议的那样(尽管我没有看到需要基于您的结构其他语句) - 或者单个变量缓存,如果您只需要知道最新的密钥。

0
额外

为什么不扩展字典类以添加最后一个键插入属性。像下面这样的东西可能吗?

public class ExtendedDictionary : Dictionary
{
    private int lastKeyInserted = -1;

    public int LastKeyInserted
    {
        get { return lastKeyInserted; }
        set { lastKeyInserted = value; }
    }

    public void AddNew(string s, int i)
    {
        lastKeyInserted = i;

        base.Add(s, i);
    }
}
0
额外
嗯?不,我不是(?)
额外 作者 Calanus,
您正在将lastKeyInserted设置为插入的最后一个值。要么你打算把它设置为最后一个键,要么你需要更好的变量和属性名称。
额外 作者 Fantius,

我认为你可以做这样的事情,语法可能是错误的,并没有在一段时间内使用C# 获取最后一个项目

Dictionary.KeyCollection keys = mydict.keys;
string lastKey = keys.Last();

或者使用Max而不是Last来获得最大值,我不知道哪一个更适合你的代码。

0
额外
尝试这为最后(当使用Dist <�字符串,字符串>显然:-) KeyValuePair last = oAuthPairs.Last();如果(kvp.Key!= last.Key){_oauth_ParamString = _oauth_ParamString +“&”; }
额外 作者 Tim Windsor,
我会补充一点,因为“Last()”是一个扩展方法,所以您需要.NET Framework 3.5并在.cs文件的顶部添加“using System.Linq”。
额外 作者 SuperOli,

In case you decide to use dangerous code that is subject to breakage, this extension function will fetch a key from a Dictionary according to its internal indexing (which for Mono and .NET currently appears to be in the same order as you get by enumerating the Keys property).

最好使用Linq: dict.Keys.ElementAt(i),但该函数将迭代O(N);以下是O(1),但有反射表现的惩罚。

using System;
using System.Collections.Generic;
using System.Reflection;

public static class Extensions
{
    public static TKey KeyByIndex(this Dictionary dict, int idx)
    {
        Type type = typeof(Dictionary);
        FieldInfo info = type.GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance);
        if (info != null)
        {
            // .NET
            Object element = ((Array)info.GetValue(dict)).GetValue(idx);
            return (TKey)element.GetType().GetField("key", BindingFlags.Public | BindingFlags.Instance).GetValue(element);
        }
        // Mono:
        info = type.GetField("keySlots", BindingFlags.NonPublic | BindingFlags.Instance);
        return (TKey)((Array)info.GetValue(dict)).GetValue(idx);
    }
};
0
额外
嗯,编辑以改善答案赚得downvote。我有没有明确表示代码(显然)是可怕的,应该相应考虑?
额外 作者 Glenn Slayden,

正如@Falanwe在评论中指出的,做这样的事情是 不正确

int LastCount = mydict.Keys.ElementAt(mydict.Count -1);

不应取决于字典中键的顺序。如果您需要订购,则应使用 OrderedDictionary ,如回答中所述。此页面上的其他答案也很有趣。

0
额外
看到这样一个公然错误的答案被接受并提升了很多,真是可怕。这是错误的,因为,正如 Dictionary < TKey,TValue> 文档声明“ Dictionary .KeyCollection 中的键的顺序未指定。”未定义的顺序,您无法确定哪个位于最后位置( mydict.Count -1
额外 作者 Falanwe,
这是可怕的...但对我来说很有帮助,因为我一直在寻求确认我怀疑你不能依靠订单!谢谢@Falanwe
额外 作者 Charlie,
似乎不适用于 HashTable System.Collections.ICollection'不包含'ElementAt'的定义,并且没有接受类型'System.Collections.ICollection'的第一个参数的扩展方法'ElementAt'可能是发现
额外 作者 v.oddou,
对于某些订单不相关 - 只是你通过所有钥匙的事实。
额外 作者 Royi Mindel,
您可以使用 ElementAtOrDefault 版本处理异常版本。
额外 作者 Tarık Özgün Gün,