Подтвердить что ты не робот

Как удалить элементы из словаря с помощью выражения лямбда

Я не использую решения LINQ,

Я использую простой предикат, чтобы определить, нужно ли удалять ключ, Например, если словарь построен как Dictionary<int, int>,  так как я должен удалить все записи с отрицательными данными

Я предпочитаю использовать тот же словарь, а не создавать новый, У меня нет проблем с подготовкой

Есть ли способ сделать это, не используя LINQ, но используя выражения Lambda?

Мне не нужны решения в LINQ, потому что никто не использует их в моем проекте, не хотел быть первым.., но поскольку я видел, как решения LINQ выглядят лучше, я буду использовать их в них.

4b9b3361

Ответ 1

Самый простой способ - создать новый словарь, если это вам подходит:

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);
}

EDIT: Я только что заметил первое предложение: "Я не в 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, я бы посоветовал вам это сделать. Мое второе решение эквивалентно "по-ручной" версии, но более читаемой ИМО.

Ответ 2

Просто используя выражение лямбда:

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

Ответ 3

var toRemove = dict.Keys.Where(predicate).ToArray();
foreach (var key in toRemove) {
    dict.Remove(key);
}

Ответ 4

Хорошо, если вы добавите

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

Ответ 5

Вы хотите удалить элементы из этого словаря, или вы счастливы использовать новый словарь без этих элементов?

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

Ответ 6

Самый простой:

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

Или просто переверните все в 'for' в обратном порядке и удалите недопустимые.

Ответ 7

Я знаю, что вы сказали, что не в Linq, но я не мог сдержать себя следующим решением, плюс это все еще полезно, если вы прочитаете заголовок вашего вопроса. Это, наверное, самое элегантное решение вашей проблемы:

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