Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
The filter function allows us to easily narrow down an array of elements to values that match a predicate. In this video, let's build the filter function!
-
0:00
One of the most common operations we conduct with arrays
-
0:03
is to iterate through it and
-
0:05
use elements that match a particular predicate or set of requirements.
-
0:10
For example, you've written code in the past to iterate through a range of values
-
0:15
using a for loop and append to a new array only the even numbered values.
-
0:20
Of course, there's another standard library function to handle
-
0:24
exactly this kind of code, the filter function.
-
0:27
So, new comment, filter.
-
0:31
As an example of how filter works, let's try and
-
0:35
get an array of even numbers from 1 to 100.
-
0:37
So I can say, let evenNumbers.
-
0:42
=, and here I'm going to create a range that goes from 1 to 100,
-
0:49
and then I'm going to call filter on it,
-
0:53
and sort out just the even numbers.
-
1:00
Super easy, just a single line of code.
-
1:03
And if I do print(evenNumbers),
-
1:05
you should see a bunch of even numbers in your console.
-
1:10
Of course, as we've been doing so far, the easiest way to understand what filter does
-
1:15
is to build a simple version ourselves.
-
1:18
And again, as with previous examples, we'll start with an extension on array.
-
1:23
Unlike map or a flat map, filter doesn't define its own
-
1:26
generic parameter because it always has a specific signature.
-
1:31
So, I'll call this customFilter.
-
1:33
Filter takes a closure as an argument with a type signature of element to bool.
-
1:39
Remember that element refers to the arrays type parameter.
-
1:43
Basically, the closure takes a generic parameter, performs some logic on
-
1:48
it to determine whether it fits our criteria, and then returns true or false.
-
1:53
If we return true from our logical check,
-
1:56
then we include the element in a new array, otherwise we don't.
-
2:01
Since we're simply filtering through an array and not transforming it,
-
2:05
the return type of filter is the same type as the existing array.
-
2:09
So, here will say, isIncluded, which is our function that checks to see if
-
2:14
we want to include this element in a new array.
-
2:18
And the signature is Element to Bool.
-
2:22
And again, because we're not transforming the return type is going to be an array of
-
2:27
the same type, so an array of Element.
-
2:31
These types of functions always return a new array because we want to maintain
-
2:35
immutability of data.
-
2:36
So, we always create a new array.
-
2:39
Like before, we'll start off with a result,
-
2:42
which is a new array that we're going to append our elements to.
-
2:45
And we'll create an empty array to start out.
-
2:48
Again, we're going to iterate through self and grab each element, but
-
2:53
this time we're going to do something special.
-
2:55
Here we're going to use a where clause.
-
2:58
A where clause, just like with generic code, is used to introduce a constraint.
-
3:04
Now, here though, it's a lot more flexible, and essentially,
-
3:08
you can provide any expression that returns a Boolean value as a condition,
-
3:12
much like any control flow statement.
-
3:15
So, after this where, we can include a predicate.
-
3:19
Which is some logic that matches an element to a set of criteria and
-
3:22
returns either true or false.
-
3:24
If true, then we enter the body of the for
-
3:27
loop, otherwise we just jump to the next iteration.
-
3:31
So, here I'm going to say for x in self where isIncluded(x).
-
3:36
What this does is it means we only enter the for
-
3:40
loop if the result of calling isIncluded on x is true.
-
3:45
So, isIncluded is the closure passed into the filter function.
-
3:49
And if we call that closure using the current value of x from the array,
-
3:53
if that's true, we step in, otherwise we just move to the next iteration.
-
3:58
So, in that case if it's true, we'll just say result.append(x).
-
4:03
Make sure you don't take result.append(contentsOf).
-
4:06
After that, all we're going to do is return results.
-
4:11
Because filter always has to return a Boolean value, the closure expression
-
4:16
we pass in must perform a comparison operation and return a Boolean.
-
4:22
So, let's look at another variation of using the accounts example.
-
4:26
Let's say in our app we displayed a central directory of all accounts,
-
4:30
much like your contacts app.
-
4:32
Just like in your contacts app, let's say there was a search bar up at the top that
-
4:37
lets you type and filter through the list.
-
4:39
This is as simple as using the filter function.
-
4:42
For example, to get all the users whose user name start with P,
-
4:49
we can say let some PUsers = allusers.customfilter.
-
4:55
And we'll pass in a closer that says {
-
4:59
$0.username.characters.first == "p"}.
-
5:06
And it should do that and if you do print(somePUsers),
-
5:10
we'll see that there are only two accounts that have user names with P.
-
5:18
Our closure expression performs an equality operation
-
5:21
to check whether the first character in the username string is equal to P.
-
5:25
This returns true if it is or false otherwise and the filter function uses
-
5:29
that value to determine whether it should be appended to the new array or not.
-
5:35
Filter is a bit more intuitive to understand than map or flat map.
-
5:39
But works much in the same way, in that it is a very general purpose function
-
5:43
that takes any kind of closure expression matching the signature required.
-
5:48
This allows you to filter through nearly everything.
-
5:51
Okay, we have map, flat map, and filter done.
-
5:54
Next, let's walk through the reduce function.
You need to sign up for Treehouse in order to download course files.
Sign up