На самом деле немного сложно указать, чего вы хотите, поэтому я возьму свои собственные предположения.
- Базовая коллекция должна быть неизменной после фильтрации
- Результат не является постоянным
Классическим подходом является использование просмотров . Это в основном ленивое программирование , где вы создаете объект, который может получить доступ к исходной коллекции и знает, какой фильтр нужно применить, но не будет выполнять никаких вычислений, пока ничего не требуется.
В коллекциях представления часто реализуются с помощью итераторов , и для фильтрации, конечно же, шаблон стратегии, как уже указывалось.
Например:
Collection myCollection;
Predicate myFilter;
// Nothing is computed here
View<Predicate> myView(myCollection, myFilter);
// We iterate until we find the first item in the collection that satisfies
// the Predicate, and no more, to initialize `begin`
View<Predicate>::Iterator begin = myView.begin(), end = myView.end();
Чистым преимуществом является то, что если вам (скажем) нужны только 10 первых элементов, то вы будете применять предикат только столько, сколько необходимо, чтобы найти эти 10 первыми, и не более.
Кроме того, нет копии задействованных элементов, и ваше представление гарантированно будет обновлено, даже если вы измените myCollection
, хотя это может повлиять на достоверность итераторов (как обычно).
Проблема в том, что (если вы не реализуете кэширование), результат вычисляется каждый раз.
Если вы хотите более устойчивый результат, то вам лучше создать новую коллекцию, содержащую только отфильтрованные элементы (или ссылки на них). Здесь нет общего шаблона, поскольку это зависит от того, как вы хотите использовать «отфильтрованный» список.
Что касается предложенного шаблона стратегии, обычно вы можете построить свой фильтр по блокам, используя составной шаблон, а затем передать созданный таким образом объект в качестве стратегии.
Составной шаблон особенно подходит для представления результата проанализированного выражения. Например, вам может понадобиться взглянуть на деревья выражений, чтобы получить представление.