layout | title | permalink |
---|---|---|
lesson |
Filter |
/filter/ |
let myListOfAges = [22, 12, 43, 44, 22, 54, 16, 87, 12];
let myListOfOldEnoughAges = [];
for(let i = 0; i < myListOfAges.length; i++) {
if(myListOfAges[i] >= 18) {
myListOfOldEnoughAges.push(myListOfAges[i]);
}
}
- Takes multiple lines to handle even the simplest filters
- Can be hard to quickly understand what is happening
- Complexity increases significantly with more complex conditions
- A functional programming tool found natively in javascript
- Creates a new array based off the data in a base array
- Does not modify the original array
- Only the items from the original array that pass a test are copied into a new array
- With the same example as above
let myListOfAges = [22, 12, 43, 44, 22, 54, 16, 87, 12];
// dont forget that 'eachAge >= 18' resolves to true or false,
// and that with arrow functions, the value on the right hand of the arrow is automatically returned
let myListOfOldEnoughAges = myListOfAges.filter(eachAge => eachAge >= 18);
filter
exists as a method on all arrays, it takes one uncalled function as an argument- This uncalled function is called for each item in the array, as filter iterates over each item
- This function is provided the value currently being iterated over as the first parameter, in the above
case, that means that
eachAge
represents22
the first time it is called, then12
, and then43
and so on. - This function expects either a
true
or afalse
to be returned inside of it. - In the above example, the first time
eachAge
is equal to22
, and22 >= 18
resolves totrue
. That true is returned, and that means that22
is kept in the next array
- Filter does not modify the original array, it creates and returns a brand new one (which generally, is a very good thing)
const allFriends = [{name: 'Sumit', isSuperFriend: true}, {name: 'Joanne', isSuperFriend: false}, {name: 'Purvi', isSuperFriend: false}];
const superFriends = allFriends.filter(friend => friend.isSuperFriend);
allFriends
does not get modified, so later references to all of your friends are still available
- You should not create a new array and push into it in your filter 'loop'
// DO NOT DO THIS
const allFriends = [{name: 'Sumit', isSuperFriend: true}, {name: 'Joanne', isSuperFriend: false}, {name: 'Purvi', isSuperFriend: false}];
const superFriends = [];
allFriends.filter(friend => {
if(friend.isSuperFriend){
superFriends.push(friend);
}
})
In the above, the filter is not being correctly used, it is being used as an iterator, no different than forEach
or a for loop.
Instead we should be ensuring that the functions being used inside of our filter are pure.
- Chaining together multiple filters, combined with other array methods, can make elaborate requirements seem trivial
// Out of a list of all my friends, get the first superFriend's with dog(s) as pets
const allFriends = [
{name: 'Sumit', isSuperFriend: true, pets: ['Cat', 'Bird']},
{name: 'Joanne', isSuperFriend: false, pets: []},
{name: 'Purvi', isSuperFriend: true, pets: ['Dog']},
{name: 'Pete', isSuperFriend: true, pets: ['Monkey', 'Dog']},
{name: 'Manal', isSuperFriend: false, pets: ['Dog']},
];
const dogOwningSuperFriends =
allFriends.filter(friend => friend.isSuperFriend) // resolves to just super friends
.filter(friend => friend.pets.includes('Dog')); // takes the list of super friends and filters it further
The above does not include the friend Manal
, because she is not a super friend, even though she has a dog
- Filtering by the position in an array can be a very useful thing
const peopleWaitingInLine = ['Della', 'Lisamarie', 'Melanie', 'Ahmed', 'Lucy', 'Purvi'];
// the first three people in line get a prize!!!!
const firstThreeInLine = peopleWaitingInLine.filter((person, index) => index < 3);
- The second parameter passed into the filter callback function is the index of the item currently being iterated over, you can use this in your filters!