如何使用lambda表达式从字典中删除项

本文关键字:删除 字典 何使用 lambda 表达式 | 更新日期: 2023-09-27 17:49:41

我使用简单的谓词来确定是否应该删除键。例如,如果字典是像Dictionary<int, int>这样的结构,我应该如何删除所有带有负值的条目?

我更喜欢用原来的字典,而不是创建一个新的。

我没有性能问题。

有没有办法做到这一点,不使用LINQ,但使用Lambda表达式?

我不想要LINQ的解决方案,因为没有人在我的项目中使用它们,不想成为第一个。但是因为我看到LINQ解决方案看起来更好,所以我将使用它们。

如何使用lambda表达式从字典中删除项

最简单的方法可能是创建一个新的字典,如果您可以的话:

var newDictionary = oldDictionary.Where(pair => pair.Value >= 0)
                                 .ToDictionary(pair => pair.Key,
                                               pair => pair.Value);

如果改变现有的字典(例如,因为其他几个对象引用同一字典),则需要构建要删除的键列表,然后再删除它们:

var toRemove = dictionary.Where(pair => pair.Value < 0)
                         .Select(pair => pair.Key)
                         .ToList();
foreach (var key in toRemove)
{
    dictionary.Remove(key);
}

编辑:我刚刚注意到第一句话:"我不喜欢LINQ解决方案"。如果这意味着您不想使用 LINQ解决方案,这里是手工版本:

List<int> toRemove = new List<int>();
foreach (KeyValuePair<int, int> pair in dictionary)
{
    if (pair.Value < 0)
    {
        toRemove.Add(pair.Key);
    }
}
foreach (var key in toRemove)
{
    dictionary.Remove(key);
}

…但是如果你可以使用LINQ,我鼓励你这样做。我的第二个解决方案相当于"手工"版本,但在IMO上更具可读性。

仅使用lambda表达式:

foreach (var i in myDict.Where(d => (d.Value  < 0 || d.key <0)).ToList() ) 
{
  myDict.Remove(i.Key);
}
var toRemove = dict.Keys.Where(predicate).ToArray();
foreach (var key in toRemove) {
    dict.Remove(key);
}

从。net Core 3.0开始,在枚举过程中删除字典项实际上是安全的。所以最简单的解决方案是:

foreach (var kv in dictionary)
    if (kv.Value < 0)
        dictionary.Remove(kv.Key);

查看Dictionary<TKey,TValue>.Remove方法文档中的注释:

。仅适用于。NET Core 3.0+:此变异方法可以安全地调用,而不会使Dictionary<TKey,TValue>实例上的活动枚举器失效。这并不意味着线程安全。

这个特性就是这样成为一件事的:允许Dictionary<K,V>。在枚举时删除。

您想要从该字典中删除这些项,还是愿意使用不包含这些项的新字典?

var d = new Dictionary<int,int>();
var newDict = d.Where(entry => entry.Value >= 0).ToDictionary(entry => entry.Key, entry => entry.Value);

最简单的:

Dictionary<long, long> dict...
Dictionary<long, long> result = dict.Were(x => x.Value >= 0).ToDictionary(x => x.Key, x => x.Value);

如果你加上

namespace MMExtensions
{
    public static class DictionaryExtensions
    {
        public delegate bool Predicate<TKey, TValue>(KeyValuePair<TKey, TValue> d);
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void Filter<TKey, TValue>(
            this Dictionary<TKey, TValue> hashtable, Predicate<TKey, TValue> p)
        {
            foreach (KeyValuePair<TKey, TValue> value in hashtable.ToList().Where(value => !p(value)))
                hashtable.Remove(value.Key);
        }
    }
}

你有一些数据集作为字典:

    Dictionary<string, int> d =
            new Dictionary<string, int> {{"v", -3}, {"val1", 1}, {"val2", 2}};

那么你可以使用:

    d.Filter(delegate(KeyValuePair<string, int> kv) { return kv.Value >= 0; });
    d.Filter(kv => kv.Value >= 0);// or as lambda

我知道你说你不喜欢Linq,但是我不能用下面的解决方案来控制自己,而且如果你读了你的问题的标题,它仍然是有用的。这可能是您的问题的最优雅的解决方案:

dictionary.Where(pair => pair.Value < 0)
          .Select(pair => { 
              dictionary.Remove(pair.Key);
              return pair.Key;
          });