【问题标题】:Dictionary: Property or indexer cannot be assigned to: it is read only字典:属性或索引器不能分配给:它是只读的
【发布时间】:2019-06-13 07:21:06
【问题描述】:

我正在尝试按如下方式更改我的字典中 Keys 的值:

//This part loads the data in the iterator
List<Recommendations> iterator = LoadBooks().ToList();
//This part adds the data to a list 
List<Recommendations> list = new List<Recommendations>();

        foreach (var item in iterator.Take(100))
        {
            list.Add(item);
        }
        //This part adds Key and List as key pair value to the Dictionary
        if (!SuggestedDictionary.ContainsKey(bkName))
        {
            SuggestedDictionary.Add(bkName, list);

        }
       //This part loops over the dictionary contents 
  for (int i = 0; i < 10; i++)
        {
            foreach (var entry in SuggestedDictionary)
            {
                rec.Add(new Recommendations() { bookName = entry.Key, Rate = CalculateScore(bkName, entry.Key) });
                entry.Key = entry.Value[i];
            }

        }

但它说“属性或索引器 KeyValuePair>.Key 无法分配给。是只读的。我真正想做的是在这里更改字典 Key 的值并为其分配另一个值。

【问题讨论】:

  • 你到底想做什么?一些输入数据和预期输出数据在这里可能会有所帮助。 (请看stackoverflow.com/help/mcve
  • 为什么需要字典?从您的代码看来,您只需要一个列表
  • 我正在尝试计算 Pearson 相关性,它需要一个 KeyValuePair 来比较内容。这就是我使用字典的原因。 @dtanabe 请检查编辑后的代码。
  • SuggestedDictionary 的类型参数是什么?
  • @dtanabe 它是一个 Dictionary> 类型字典

标签: c# dictionary key setter keyvaluepair


【解决方案1】:

这样做的唯一方法是删除并重新添加字典项。

为什么?这是因为字典在称为链和桶的过程上工作(它类似于具有不同冲突解决策略的哈希表)。

当一个项目被添加到字典中时,它会被添加到它的键散列到的存储桶中,如果那里已经有一个实例,它会被添加到一个链表中。如果您要更改密钥,则需要完成确定其所属位置的过程。因此,最简单、最明智的解决方案就是删除并重新添加该项目。

解决方案

var data = SomeFunkyDictionary[key];
SomeFunkyDictionary.Remove(key);
SomeFunkyDictionary.Add(newKey,data);

或者让你自己成为一个扩展方法

public static class Extensions
{
   public static void ReplaceKey<T, U>(this Dictionary<T, U> source, T key, T newKey)
   {
      if(!source.TryGetValue(key, out var value))
         throw new ArgumentException("Key does not exist", nameof(key));
      source.Remove(key);
      source.Add(newKey, value);
   }
}

用法

SomeFunkyDictionary.ReplaceKey(oldKye,newKey);

旁注:在字典中添加和删除会受到惩罚;如果您不需要快速查找,那么根本不使用字典或使用其他策略可能更合适。

【讨论】:

  • 非常好的和说明性的答案 +1
  • 我用上面的代码试过了,但它说集合已被修改,枚举操作可能无法执行。
  • 那是因为你在 foreach 循环中修改了字典。如果您想毫无例外地处理它,您可以尝试从中取出所有密钥并进行处理。 "var keys = SuggestedDictionary.Keys; foreach (var key in keys) { DoSomething(SuggestedDictionary[key]); }"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多