【问题标题】:Efficient way to remove all entries in a dictionary lower than a specified value删除字典中低于指定值的所有条目的有效方法
【发布时间】:2010-03-02 15:59:43
【问题描述】:

我需要根据指定的下限删除字典中的所有条目。

我目前的解决方案是这样的:

    List<string> keys = new List<string>();

    foreach (KeyValuePair<string, int> kvp in dic)
    {
        if (kvp.Value < lowerBound)
            keys.Add(kvp.Key);
    }

    foreach (string key in keys)
        dic.Remove(key);

然而,这是相当昂贵的,特别是因为字典的大小相当大。

我见过这样的 LINQ 解决方案:

foreach(var kvp in dic.Where(kvp.Value <= lowerBound).ToDictionary())
{
    dic.Remove(kvp.Key);
}

我认为它更好,因为它只有 1 个 foreach,但我得到了:

当前上下文中不存在名称“kvp”

无法从用法中推断方法“System.Linq.Enumerable.Where(System.Collections.Generic.IEnumerable, System.Func)”的类型参数。尝试明确指定类型参数。

我承认我对 LINQ 一无所知,所以有什么想法可以使第二个解决方案或更好的解决方案发挥作用吗?

【问题讨论】:

  • 如果您经常执行此下限删除,那么 Dictionary 可能不适合您。
  • 幸运的是我只需要做一次。

标签: c# linq .net-3.5 dictionary


【解决方案1】:

不要显式删除它们,而是仅使用高于该下限的值重新分配字典:

dic = dic.Where(kvp => kvp.Value > lowerBound).ToDictionary();

这样你就可以完全消除你在那里的 foreach 循环。

此外,您收到该错误的原因是您没有使用正确的 lambda 语法。实际上,您根本没有使用 lambda。表达式:

kvp => kvp.Value > lowerBound

是一种方法的简写,它采用一个参数,称为“kvp”,并返回表达式的评估:

kvp.Value > lowerBound

=&gt; 称为“lambda 运算符”,它将参数输入与返回的输出分开。每个接受 Func 的 LINQ 方法都在请求某种委托,为简洁起见,通常表示为 lambda 表达式。当你给它一个 lambda 表达式时,编译器将停止抱怨。

阅读this 了解有关 lambda 表达式的更多信息。

【讨论】:

  • 目前只回答问题,而不是语法错误。
  • Thnx,在将参数添加到 ToDictionary(kvp => kvp.key, kvp => kvp.value) 后它可以工作
  • 我很惊讶这是有效的。我猜 Linq 很神奇!
  • 请注意,LINQ 不是魔法,它只是一个很好的语法。即使您可以在一行中重新分配字典,它的性能或多或少与在 foreach loo 中“手动”创建它的性能相同。
  • ToDictionary 什么时候采用零参数?
【解决方案2】:

试试这个。

foreach(var kvp in dic.Where(x => x.Value <= lowerBound).ToDictionary())
{
    dic.Remove(kvp.Key);
}

【讨论】:

    【解决方案3】:
    dic.Where(kvp.Value <= lowerBound)
    

    替换为

    dic.Where(kvp1 => kvp1.Value <= lowerBound)
    

    【讨论】:

      猜你喜欢
      • 2014-11-02
      • 2016-08-27
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多