根据值获取C#字典中键/值对的索引

我想知道是否存在一些获取特定值索引的属性或方法。

我发现字典有Contains()方法,如果传入的值存在则返回true,所以这个方法几乎实现了我需要的东西。

我知道我可以循环遍历所有的值对并检查条件,但我问,因为可能有一种优化的方法来做到这一点。

字典中没有“索引”这样的概念 – 它基本上是无序的。 当然,当您迭代它时,您将按某种顺序获取项目,但该顺序无法保证并且可能随时间而变化(特别是如果您添加或删除条目)。

显然,只需使用Key属性就可以从KeyValuePair获取密钥,这样就可以使用字典的索引器了:

 var pair = ...; var value = dictionary[pair.Key]; Assert.AreEqual(value, pair.Value); 

你还没有真正说出你想要做的事情。 如果您正在尝试查找与特定值对应的某个键,则可以使用:

 var key = dictionary.Where(pair => pair.Value == desiredValue) .Select(pair => pair.Key) .FirstOrDefault(); 

如果条目不存在,则key将为null。

这假设键类型是引用类型…如果它是值类型,则需要稍微不同地执行操作。

当然,如果你真的想按键查找值,你应该考虑使用另一个字典,除了你现有的字典之外,它还反过来映射。

假设您有一个名为fooDictionary的词典

 fooDictionary.Values.ToList().IndexOf(someValue); 

Values.ToList()将您的字典值转换为someValue对象的List。

IndexOf(someValue)搜索新列表,查找有问题的someValue对象,并返回与字典中键/值对的索引匹配的索引。

此方法不关心字典键,它只返回您要查找的值的索引。

但是,这并不能解决可能存在多个匹配的“someValue”对象的问题。

考虑使用System.Collections.Specialized.OrderedDictionary ,虽然它不是通用的,或者实现自己的( 示例 )。

OrderedDictionary不支持IndexOf ,但它很容易实现:

 public static class OrderedDictionaryExtensions { public static int IndexOf(this OrderedDictionary dictionary, object value) { for(int i = 0; i < dictionary.Count; ++i) { if(dictionary[i] == value) return i; } return -1; } } 

您可以使用LINQ来帮助您。

 Dictionary dict = new Dictionary(); dict.Add(1, "hi"); dict.Add(2, "NotHi"); dict.Add(3, "Bah"); var item = (from d in dict where d.Value == "hi" select d.Key).FirstOrDefault(); Console.WriteLine(item); //Prints 1 

如果要搜索值, 则必须遍历所有数据 。 但是为了最小化所涉及的代码,您可以使用LINQ

例:

给定字典定义如下:

 Dictionary dict; 

您可以使用以下代码:

 // Search for all keys with given value Int32[] keys = dict.Where(kvp => kvp.Value.Equals("SomeValue")).Select(kvp => kvp.Key).ToArray(); // Search for first key with given value Int32 key = dict.First(kvp => kvp.Value.Equals("SomeValue")).Key; 
    您可以在字典中按键/值查找索引
 Dictionary myDictionary = new Dictionary(); myDictionary.Add("a", "x"); myDictionary.Add("b", "y"); int i = Array.IndexOf(myDictionary.Keys.ToArray(), "a"); int j = Array.IndexOf(myDictionary.Values.ToArray(), "y"); 

不,没有类似的IndexOf for Dictionary虽然你可以利用ContainsKey方法来获取一个键是否属于字典

在你对max的回答的评论中,你说你真正想要得到的是包含特定值的KeyValuePair的关键 ,而不是索引 。 您可以编辑您的问题以使其更清晰。

值得指出的是( EricM在他的回答中已经提到过这一点),一个值可能在字典中出现不止一次 ,在这种情况下,人们必须考虑他想要获得哪个密钥:例如,第一个出现的密钥,最后,所有这些?

如果您确定每个键都具有唯一值 ,则可以使用另一个字典,其中第一个值用作键,而前一个键用作值。 否则,第二个字典的想法(由Jon Skeet 建议 )将无法工作,因为您将再次考虑在新字典中使用哪个可能的键作为值。

但是, 如果您询问索引,EricM的答案就可以了。 然后你可以使用以下方法获得有问题的KeyValuePair:

 yourDictionary.ElementAt(theIndexYouFound); 

只要您不在您的yourDictionary添加/删除内容。

PS:我知道它已经差不多7年了,但是到底是什么。 我认为最好将我的答案表达为解决OP,但当然现在可以说这是除了 OP之外的其他任何人的答案。 完全了解这一点,谢谢。