Skip to main content

Filtering a Collection

Filtering means picking out the elements of a collection that match a condition.

The condition is written as a function that takes one element and returns true (keep it) or false (skip it). Such a function is called a predicate.

Filtering builds a new array. The original array is not changed.

Arrays already have a filter() method, so you do not write a helper of your own. You call it on the array and pass the predicate: words.filter(s => s.length > 3).

Only arrays have filter(). A Map does not, so you turn it into an array of pairs first, filter that array, and build a new Map from the result.

Be careful with splice(). It also removes elements, but it changes the original array instead of making a new one.


Filter by Predicate

The simplest way to filter is to pass a predicate to filter(). The method walks through the array and keeps every element that passes the test.

A Map has no filter() of its own. Spread it with [...m] into an array of [key, value] pairs, filter those pairs, and pass the result to new Map().

If the condition also needs the position of the element, use the second argument of the predicate. It is the index.

To keep the elements that do not match, put ! in front of the condition. There is no separate filterNot().

An array of type (string | number | null)[] can hold values of different types. A type guard — a function whose return type is written v is string — tells TypeScript which values survived the filter, so the result has type string[]. The same trick removes null and undefined, the two values that mean "no value".

Filter an array

Keep only the words that are longer than 3 letters. The condition s.length > 3 is passed to filter() as an arrow function. The result is a new array, [ 'three', 'four' ].

Prompt
Write a TypeScript program that takes the words one, two, three, four in a string array and uses filter() with a predicate to keep the words longer than 3 letters. Print the resulting array.
Output: TypeScript file and captured output
Filter an array

Filter a Map

Spread the Map into [key, value] pairs and keep the pairs whose key ends with "1" and whose value is greater than 10. endsWith() checks the end of a string. Only one pair is left, so the new Map prints as Map(1) { 'key11' => 11 }.

Prompt
Write a TypeScript program that builds a Map from the keys key1, key2, key3, key11 to the values 1, 2, 3, 11. Spread the Map into pairs, keep only the pairs whose key ends with "1" and whose value is greater than 10, build a new Map from them and print it.
Output: TypeScript file and captured output
Filter a Map

Filter using the index

The predicate can take a second argument: the index of the element. Keep a word only when its index is not 0 and it has fewer than 5 letters.

Prompt
Write a TypeScript program that takes the words one, two, three, four and uses filter() with a predicate that also takes the index. Keep a word only if its index is not 0 and it is shorter than 5 letters, then print the result.
Output: TypeScript file and captured output
Filter using the index

Filter with a negated condition

Drop the words with 3 letters or fewer. The condition s.length <= 3 is negated with !, so only the longer words stay.

Prompt
Write a TypeScript program that takes the words one, two, three, four and uses filter() with the condition s.length <= 3 negated by !, so words with 3 letters or fewer are dropped. Print the result.
Output: TypeScript file and captured output
Filter with a negated condition

Filter by type

The array holds null, two numbers and two strings. The type guard (v): v is string => typeof v === "string" keeps only the strings, and it also narrows the type: strings has type string[], so toUpperCase() is allowed on its elements. Each string is printed in upper case, one per line.

Prompt
Write a TypeScript program with an array of type (string | number | null)[] holding null, 1, "two", 3.5 and "four". Filter it with a type guard whose return type is v is string, so the result has type string[]. Print each string in upper case, one per line.
Output: TypeScript file and captured output
Filter by type

Filter out null and undefined

The array holds strings mixed with null and undefined. The type guard keeps the values that are neither, so the result has type string[] — the nullish part of the type is gone, and the strings can be used without another check.

Prompt
Write a TypeScript program with an array of type (string | null | undefined)[] holding null, "one", undefined and "two". Filter it with a type guard that removes null and undefined, so the result has type string[]. Print the result.
Output: TypeScript file and captured output
Filter out null and undefined

Partition

Sometimes you want both groups: the elements that match and the ones that do not.

There is no built-in partition(). A small generic helper does it: it loops once and pushes each element into either the match array or the rest array. The helper returns both arrays as a tuple — an array with a fixed length and a type for each position — and you unpack it with const [match, rest] = ....

Split an array in two

Words longer than 3 letters go into match; all the others go into rest. Both arrays are printed, on two lines.

Prompt
Write a TypeScript program with a generic partition helper that splits an array into a tuple of two arrays: the elements that pass a condition and the rest. Use it on the words one, two, three, four with the condition "longer than 3 letters", then print the matching array and the rest on two lines.
Output: TypeScript file and captured output
Split an array in two

Test Predicates

Sometimes you do not need the matching elements, only a yes or no answer.

  • any: does at least one element pass the test? some() answers this.
  • none: does no element pass the test? Put ! in front of some().
  • all: does every element pass the test? That is every().

Both methods stop as soon as the answer is known. some() stops at the first element that passes, every() at the first one that fails.

Without a condition, "any element at all?" is words.length > 0 and "no element at all?" is words.length === 0.

On an empty array, every() returns true. There is no element that fails the test, so the test is never broken. This is called vacuous truth.

any

Check whether at least one word ends with "e", then check whether the array has any element at all. Both answers are true.

Prompt
Write a TypeScript program that takes the words one, two, three, four. Use some() to check whether at least one word ends with "e" and print the answer. Then print whether the array has any element at all by checking that its length is greater than 0.
Output: TypeScript file and captured output
any

none

Check that no word ends with "a", which is true, then check whether the array is empty, which is false.

Prompt
Write a TypeScript program that takes the words one, two, three, four. Use ! with some() to check that no word ends with "a" and print the answer. Then print whether the array is empty by checking that its length equals 0.
Output: TypeScript file and captured output
none

all

Check whether every word ends with "e". "two" does not, so the answer is false. Then call every() on an empty array, which gives true.

Prompt
Write a TypeScript program that takes the words one, two, three, four. Use every() to check whether all of them end with "e" and print the answer. Then call every() with the same condition on an empty string array and print the answer.
Output: TypeScript file and captured output
all