by Cathal Weakliam
Loops are the standard way to process collections like arrays and lists. However, some loops implement the same patterns repeatedly, leading to duplicate code. Higher-order functions—functions that use other functions as inputs or outputs—can reduce duplication by providing a simpler way to express common operations with collections.
Consider these two loops in JavaScript that decide if every object in an array meets a condition:
let everyRequestValid = true; | let everyUserEligible = true; |
The high similarity between the two loops violates the Don’t Repeat Yourself principle and creates an unnecessary burden on readers and maintainers of the code.
To reduce the maintenance burden, use the every method to replace each loop with a single expression. (In other languages every may have a different name, like all or allMatch).
if (requests.every(isValid)) { | if (users.every(isEligible)) { |
Processing collections with higher-order functions has several benefits:
- It significantly reduces duplication by abstracting away the common looping code.
- The resulting code is much shorter and simpler, with less opportunity for bugs.
- A reader can quickly see the intent of the code as it is not obscured behind low-level control flow.
Two other common higher-order functions are map (apply a function to each element of a collection) and filter (select the elements of a collection that pass a predicate). While the exact syntax varies by language, here’s how they look in JavaScript (using an anonymous function as the argument):
// Double each value in `ints` | // Get only the even values in `ints` |
Just don’t overdo it! Don’t rewrite a loop with functions if it makes it harder to understand, or if it would be considered unidiomatic in your language (for example, in Python, list comprehensions are equivalent to map and filter but are usually preferred).