Каждое предлагаемое здесь решение, которое использует процедуру для удаления элемента один за другим, имеет одну ошибку. Представьте, что у вас много предметов в наблюдаемой коллекции, скажем 10.000 предметов. Затем вы хотите удалить элементы, которые удовлетворяют некоторому условию.
Если вы используете решение из Daniel Hilgarth
и звоните: c.Remove(x => x.IsSelected);
и, например, 3000 предметов, которые нужно удалить, предлагаемое решение сообщит об удалении каждого элемента. Это связано с тем, что внутренняя реализация Remove(item)
уведомляет об этом изменении. И это будет вызвано для каждого из 3000 элементов в процессе удаления.
Поэтому вместо этого я создал потомка ObservableCollection и добавил новый метод RemoveAll(predicate)
[Serializable]
public class ObservableCollectionExt<T> : ObservableCollection<T>
{
public void RemoveAll(Predicate<T> predicate)
{
CheckReentrancy();
List<T> itemsToRemove = Items.Where(x => predicate(x)).ToList();
itemsToRemove.ForEach(item => Items.Remove(item));
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
Интересная строка itemsToRemove.ForEach(item => Items.Remove(item));
. Вызов напрямую Items.Remove(item)
не будет уведомлять об удалении элемента.
Вместо этого после удаления необходимых элементов изменения сообщаются сразу по вызовам:
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
Эта функция использует словарь вторичных цветов и цветов их компонентов и проверяет, является ли набор цветов компонентов подмножеством набора цветов, переданных ему:
secondary_colours = {"green": ("yellow", "blue"),
"purple": ("blue", "red"),
"orange": ("red", "yellow"),
"grey": ("white", "black"),
"beige": ("white", "yellow"),
"brown": ("black", "yellow")}
def obtainable_colours(primary_colours):
"""Returns a list of secondary colours obtainable
from combinations of the primary colours provided.
Assumes additive pigment mixing as defined above."""
global secondary_colours
response = []
for s_col,components in secondary_colours.items():
if set(components) < set(primary_colours):
response.append(s_col)
return response
Тест:
p1 = ['white','black','yellow']
p2 = ['yellow','white','black','red']
p3 = ['blue','yellow','red']
p4 = ['white','red','blue']
for p in [p1,p2,p3,p4]:
print(p)
print(obtainable_colours(p))
print("\n")
>>>
['white', 'black', 'yellow']
['grey', 'beige', 'brown']
['yellow', 'white', 'black', 'red']
['orange', 'grey', 'beige', 'brown']
['blue', 'yellow', 'red']
['green', 'purple', 'orange']
['white', 'red', 'blue']
['purple']