Как удалить элементы из словаря с помощью выражения лямбда
Я не использую решения LINQ,
Я использую простой предикат, чтобы определить, нужно ли удалять ключ,
Например, если словарь построен как Dictionary<int, int>
,
так как я должен удалить все записи с отрицательными данными
Я предпочитаю использовать тот же словарь, а не создавать новый,
У меня нет проблем с подготовкой
Есть ли способ сделать это, не используя LINQ, но используя выражения Lambda?
Мне не нужны решения в LINQ, потому что никто не использует их в моем проекте, не хотел быть первым.., но поскольку я видел, как решения LINQ выглядят лучше, я буду использовать их в них.
Ответы
Ответ 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;
});