Как я могу удалить элементы из словаря с помощью лямбда-выражения - PullRequest
31 голосов
/ 10 апреля 2011

Я не в решениях LINQ,

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

Я предпочитаю использовать один и тот же словарь, а не создавать новый, у меня нет проблем с преформойиспользуя лямбда-выражения?

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

Ответы [ 7 ]

67 голосов
/ 10 апреля 2011

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

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, я бы посоветовал вам сделать.Мое второе решение эквивалентно версии «от руки», но более читабельно для ИМО.

8 голосов
/ 10 апреля 2011

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

foreach (var i in myDict.Where(d => (d.Value  < 0 || d.key <0)).ToList() ) 
{
  myDict.Remove(i.Key);
}
2 голосов
/ 10 апреля 2011
var toRemove = dict.Keys.Where(predicate).ToArray();
foreach (var key in toRemove) {
    dict.Remove(key);
}
1 голос
/ 10 апреля 2011

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

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
0 голосов
/ 06 июля 2019

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

dictionary.Where(pair => pair.Value < 0)
          .Select(pair => { 
              dictionary.Remove(pair.Key);
              return pair.Key;
          });
0 голосов
/ 10 апреля 2011

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

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

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

0 голосов
/ 10 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...