Use NSPredicate filtering dates in collections

Recently I was building a data structure, where I store some dates of events in an array. When i was wondering, how to create a filter based on from and to dates, my first taught was: I just need to go through each element of the array an figure out, if it should be filtered out, or not.

But there is a better way to do this, it is called NSPredicate. If you have ever heard about SQL and particularly the WHERE clause, you will get the NSPredicate easily. With the predicate you can define a string which is evaluated on each object of a given set, and depending the evaluation true or false, it will add the object to the output set. It is almost similar to the basic filter capabilities of the WHERE clause in SQL.

Let see it on an example. I created 3 dates (yesterday, today and tomorrow), and I filter out the dates less than or equal to today:

The output will be the following (if today is 2016-11-18):
Filtered Array: (
"2016-11-18 14:36:18 +0000",
"2016-11-19 14:36:18 +0000"
Filtered Set: {(
2016-11-18 14:36:18 +0000,
2016-11-19 14:36:18 +0000

If you take a closer look on the predicate string: @"self >= %@", you will notice that it is using the self keyword, and this is exactly what you are thinking about. We can do a filtering on the set, which has complex objects as elements. For example, if I have an array of person object, with properties of name, surname, and dateOfBirth, I can still apply the filter on the array, modifying the predicate string to use the dot notation for the date of birth:

[NSPredicate predicateWithFormat:@"self.dateOfBirth <= %@", today];

Obviously you can use NSPredicate with different filtering data as well in collections, I would like to just emphasise that it could be very helpful for date based filtering.

Keep in mind, that NSDate contains the hour, minute and seconds information too! It can give you false comparison result. One trick is to mitigate the risk to zero out the time component. You can find an example here:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.