Keeping the Elements You Want
map changes every element. filter chooses elements. Your callback returns true or false for each element, and the elements that get true go into a new array:
const nums = [5, 3, 8, 1, 9, 2];
console.log(nums.filter(n => n > 4));
console.log(nums.filter(n => n % 2 === 0));
Output:
[ 5, 8, 9 ]
[ 8, 2 ]
Read the callback as a question: "is n greater than 4?" The elements that pass stay, in their original order. The others are left out. A function that answers yes or no like this is called a predicate. The second line uses the predicate n % 2 === 0, which keeps the even numbers.
If no element passes, you get an empty array. That is not an error:
<!-- continues -->console.log(nums.filter(n => n > 100));
Output:
[]
An empty array is still an array, so the rest of your code can work with it.
filter returns an array, so you can call map on the result. This keeps the numbers greater than 4 and then squares them:
const big = nums.filter(n => n > 4);
console.log(big.map(n => n * n));
console.log(nums.filter(n => n > 4).map(n => n * n));
Output:
[ 25, 64, 81 ]
[ 25, 64, 81 ]
The last line does the same work in one expression, without the variable big. Read it from left to right: keep the numbers greater than 4, then square them. Calling one method right after another like this is called chaining. The last lesson of this section shows more of it.
The callback does not have to return exactly true or false. A truthy value keeps the element and a falsy value drops it. For example, a length of 0 is falsy, so this keeps only the words that are not empty:
const words = ["tea", "", "jam", ""];
console.log(words.filter(w => w.length));
Output:
[ 'tea', 'jam' ]
In the exercise, keep the numbers over a threshold, keep the even numbers, then filter and square in one chain.