如何索引C#Dictionary的Values属性

时间:2012-03-26 17:39:58

标签: c# dictionary

使用C#Dictionary的Values属性,

var  myDict =  Dictionary < string, object> ;

我如何获得

中的值
  myDict.Values 

我试过

var theVales = myDict.Values ; 
object obj = theValues[0] ;

但这是语法错误。

添加了: 我试图比较两个字典中的值  相同的钥匙

4 个答案:

答案 0 :(得分:5)

你做不到。这些值没有固定的顺序。您可以将值写入新的List<object>并将其编入索引,但显然,如果字典的内容经常更改,这并不是非常有用。

你也可以使用linq:myDict.Values.ElementAt(0)但是:

  • 随着字典的增长,元素将改变位置
  • 这是非常低效的,因为它只是在给定迭代次数的Values集合上调用foreach

您也可以使用SortedList<TKey, TValue>。这会根据键维护顺序,这可能是您想要的,也可能不是您想要的,它允许您按键或索引访问值。然而,在某些情况下它具有非常不幸的性能特征,所以要小心!

这是一个linq解决方案,用于确定匹配键的值是否也匹配。这仅适用于您为密钥类型使用默认的相等比较器。如果您正在使用自定义相等比较器,则可以使用方法调用语法来执行此操作。

IEnumerable<bool> matches = 
    from pair1 in dict1
    join pair2 in dict2
        on pair1.Key equals pair2.Key
    select pair1.Value.Equals(pair2.Value)

bool allValuesMatch = matches.All();

如果您要求一个词典中的所有项目在另一个词典中都有匹配的项目,您可以这样做:

bool allKeysMatch = new HashSet(dict1.Values).SetEquals(dict2.ValueS);
bool dictionariesMatch = allKeysMatch && allValuesMatch;

答案 1 :(得分:3)

好吧,如果确实必须使用Enumerable.ElementAt,那么你不应该期望订单稳定或有意义。或者,请致电ToArrayToList进行复印。

通常,如果您要迭代它们,则只使用Values。你究竟想在这做什么?您是否了解Dictionary<,>中的条目顺序未定义?

编辑:听起来像你想要的东西:

var equal = dict1.Count == dict2.Count &&
            dict1.Keys.All(key => ValuesEqual(key, dict1, dict2));

...
private static bool ValuesEqual<TKey, TValue>(TKey key,
    IDictionary<TKey, TValue> dict1,
    IDictionary<TKey, TValue> dict2)
{
    TValue value1, value2;
    return dict1.TryGetValue(out value1) && dict2.TryGetValue(out value2) &&
           EqualityComparer<TValue>.Default.Equals(value1, value2);
}

编辑:请注意,这并不像它可能的那么快,因为它在两个词典上执行查找。这将更有效,但不太优雅的IMO:

var equal = dict1.Count == dict2.Count &&
            dict1.All(pair  => ValuesEqual(pair.Key, pair.Value, dict2));

...
private static bool ValuesEqual<TKey, TValue>(TKey key, TValue value1,
    IDictionary<TKey, TValue> dict2)
{
    TValue value2;
    return dict2.TryGetValue(out value2) &&
           EqualityComparer<TValue>.Default.Equals(value1, value2);
}

答案 2 :(得分:1)

要添加到@ JonSkeet的答案,Dictionary<TKey, TValue>由HashTable支持,这是一种无序的数据结构。因此,值的索引毫无意义 - 例如,A,B,C一次调用,C,B,A与下一次调用完全有效。

编辑:

基于你对JS的答案所作的评论(“我试图比较两个字典中的值与相同的键”),你需要这样的东西:

public boolean DictionariesContainSameKeysAndValues<TKey, TValue>(Dictionary<TKey, TValue> dict1, Dictionary<TKey, TValue> dict2) {
    if (dict1.Count != dict2.Count) return false;
    for (var key1 in dict1.Keys)
        if (!dict2.ContainsKey(key1) || !dict2[key1].Equals(dict1[key1]))
            return false;
    return true;
}

答案 3 :(得分:0)

您可以使用Indexer属性来查找字符串Key。 它仍然不是一个指数而是另一种方式:

using System.Collections.Generic;
...
class Client
{
   private Dictionary<string, yourObject> yourDict 
      = new Dictionary<string, yourObject>();

   public void Add (string id, yourObject value)
      { yourDict.Add (id, value); }

   public string this [string id]      // indexer
   {
   get { return yourDict[id]; }
   set { yourDict[id] = value; }
   }
}

public class Test
{
   public static void Main( )
   {
      Client client = new Client();
      client.Add("A1",new yourObject() { Name = "Bla",...);
      Console.WriteLine ("Your result: " + client["A1"]); // indexer access
    }   
}