It's a bit difficult to actually point out what you want, so I'll take my own assumptions.
- The underlying collection should be unchanged after the filtering
- The result is not persistent
A classic approach is the use of views. This is basically lazy programming, where you create an object which can access the original collection and knows the filter to apply but will not make any computation as long as nothing is required.
On collections, the views are often implemented with iterators, and for the filtering, of course a Strategy Pattern as already pointed out.
For example:
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();
The net advantage is that if you (say) only need the 10 first items, then you'll only apply the predicate as much as necessary to find those 10 first, and no more.
Also, there is no copy of the elements involved, and your view is guaranteed to be updated even if you modify myCollection
, although this may affect the validity of the iterators (as usual).
The problem is that (unless you implement caching), the result is computed each time.
If you want a more persistent result, then you'd better build a new collection containing only the filtered items (or references to them). There is no general pattern here for it depends on how you want to use the 'filtered' list.
As for the Strategy Pattern suggested, you can usually build your filter by block using the Composite Pattern and then pass the object thus built as the strategy.
The Composite Pattern is especially suited to represent the result of a parsed expression for example, you might want to have a look at expressions trees to get an idea.