【问题标题】:Remove Item in Dictionary based on Value根据值删除字典中的项目
【发布时间】:2009-10-28 12:16:08
【问题描述】:

我有一个Dictionary<string, string>

我需要在该字典中查看是否存在基于其他地方的输入的值,如果存在则将其删除。

ContainsValue 只是表示真/假,而不是该项目的索引或键。

救命!

谢谢

编辑:刚刚找到这个 - 你怎么看?

var key = (from k in dic where string.Compare(k.Value, "two", true) ==
0 select k.Key).FirstOrDefault();

编辑 2:我也刚刚敲了这个可能有用的

foreach (KeyValuePair<string, string> kvp in myDic)
{
    if (myList.Any(x => x.Id == kvp.Value))
        myDic.Remove(kvp.Key);
}

【问题讨论】:

  • 我认为您需要一本 BiDictionary。检查这个问题:stackoverflow.com/questions/255341/…
  • @Edit 2:您要在枚举集合时从集合中删除内容?这不会引发异常吗?
  • @JustLoren - 好点!将枚举列表并运行 LINQ 以查找密钥(如果存在),然后直接从我的字典中调用 remove
  • @Jon,foreach 也可以,只要在找到并删除密钥后添加一个中断即可。

标签: c# .net linq dictionary


【解决方案1】:

您是要删除单个值还是所有匹配值?

如果您尝试删除单个值,您如何定义要删除的值?

查询值时没有返回键的原因是字典可能包含与指定值配对的多个键。

如果您希望删除所有相同值的匹配实例,您可以这样做:

foreach(var item in dic.Where(kvp => kvp.Value == value).ToList())
{
    dic.Remove(item.Key);
}

如果你想删除第一个匹配的实例,你可以查询找到第一个项目并删除它:

var item = dic.First(kvp => kvp.Value == value);

dic.Remove(item.Key);

注意:ToList() 调用对于将值复制到新集合是必需的。如果未进行调用,则循环将修改它正在迭代的集合,从而在删除第一个值后的下一次迭代尝试中引发异常。

【讨论】:

  • 第一个代码示例不起作用,因为它不允许在 foreach 循环中修改集合。
  • 匿名编辑删除了一些必要的代码。我会把它放回去。
  • 在第二种情况下,您将通过使用以下查询获得更好的性能:foreach(var item in dic.Where(kvp =&gt; kvp.Value == value).Take(1).ToList()),这也使得break 变得不必要。
  • ToList 的技巧很聪明……它可以让我免于我写过的几乎每个for 循环。
【解决方案2】:
Dictionary<string, string> source
//
//functional programming - do not modify state - only create new state
Dictionary<string, string> result = source
  .Where(kvp => string.Compare(kvp.Value, "two", true) != 0)
  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
//
// or you could modify state
List<string> keys = source
  .Where(kvp => string.Compare(kvp.Value, "two", true) == 0)
  .Select(kvp => kvp.Key)
  .ToList();

foreach(string theKey in keys)
{
  source.Remove(theKey);
}

【讨论】:

    【解决方案3】:

    遍历字典以找到索引,然后将其删除。

    【讨论】:

    • 如已接受的答案中所述,如果您在遍历字典时删除了一个字典项,如果字典中在您删除的项之后还有剩余的值,则会引发错误。
    【解决方案4】:

    您可以使用以下方法:

        public static void RemoveAllByValue<K, V>(this Dictionary<K, V> dictionary, V value)
        {
            foreach (var key in dictionary.Where(
                    kvp => EqualityComparer<V>.Default.Equals(kvp.Value, value)).
                    Select(x => x.Key).ToArray())
                dictionary.Remove(key);
        }
    

    【讨论】:

      【解决方案5】:

      您可以使用以下作为扩展方法

       public static void RemoveByValue<T,T1>(this Dictionary<T,T1> src , T1 Value)
          {
              foreach (var item in src.Where(kvp => kvp.Value.Equals( Value)).ToList())
              {
                  src.Remove(item.Key);
              }
          }
      

      【讨论】:

      【解决方案6】:

      就我而言,我使用这个

        var key=dict.FirstOrDefault(m => m.Value == s).Key;
                  dict.Remove(key);
      

      【讨论】:

      猜你喜欢
      • 2013-02-16
      • 2018-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 2016-03-13
      • 1970-01-01
      相关资源
      最近更新 更多