如何为 C# 字典的“值”属性编制索引

本文关键字:属性 索引 字典 | 更新日期: 2023-09-27 18:29:00

使用 C# 字典的 Values 属性,

var  myDict =  Dictionary < string, object> ;

我将如何获取值

  myDict.Values 

我试过了

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

但这是一个语法错误。

添加:我正在尝试比较两个词典中的值 相同的键

如何为 C# 字典的“值”属性编制索引

你不能。 这些值没有固定的顺序。 您可以将这些值写入新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;

好吧,如果你真的有必要,你可以使用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);
}

为了补充@JonSkeet的答案,Dictionary<TKey, TValue>由HashTable支持,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;
}

可以使用索引器属性来查找字符串 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
    }   
}