Functional programming is a paradigm that emphasizes the use of pure functions, immutable data, and higher-order abstractions. One of the most common and powerful higher-order abstractions in functional programming is the reduce function.
The reduce function takes an iterable (array, list, or other collection) and a function that combines two values, and applies that function to all the elements of the iterable returning a single value (which could be a primitive or an object). The canonical example is summing up an array of numbers.
# Python code
numbers = [1, 2, 3, 4, 5]
sum = reduce(lambda x, y: x + y, numbers)
assert (sum == 15) # True
// Typescript code
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((x, y) => x + y);
assert (sum === 15); // true
The power of the reduce function is its versatility. It can be used to implement many other iterable operations such as map, filter, find, etc.
For example, a filter function is just an implementation of reduce. Let’s see how we can use the reduce function to create our own filter function. A filter function takes an iterable and a predicate (a function that returns true or false), and returns a new object with only the elements that satisfy the predicate. To use the reduce function as a filter function, we need to define a filter function.
# Python code
def filter_by(acc, cur):
# Check if the current element satisfies the condition using the boolean function
if condition(cur):
# If True, append the current element to the accumulator array
acc.append(cur)
# Return the accumulator list
return acc
// Typescript code
function filterBy(acc: any[], cur: any): any[] {
// Check if the current element satisfies the condition using the boolean function
if (condition(cur)) {
// If true, push the current element to the accumulator array
acc.push(cur);
}
// Return the accumulator array
return acc;
}
Now we can use this function with the reduce function to filter out the even numbers from an array of numbers.
# Python code
numbers = [1, 2, 3, 4, 5]
# Define a boolean function that checks if a number is odd
def condition(x):
return x % 2 == 1
# Use reduce and filter_by to filter out the even numbers from numbers
odd_numbers = reduce(filter_by, numbers, [])
print(odd_numbers) # [1, 3, 5]
// Typescript code
const numbers = [1, 2, 3, 4, 5];
// Define a boolean function that checks if a number is odd
function condition(x: number): boolean {
return x % 2 == 1;
}
// Use reduce and filterBy to filter out the even numbers from numbers
const oddNumbers: number[] = numbers.reduce(filterBy, []);
console.log(oddNumbers); // [1,3,5]
Now, let's use reduce to return a Record object. If you have an array of strings that represent colors, you can use a reduce function to count how many times each color appears in the array and return an object with the color names as keys and the counts as values.
# Import reduce from functools module
from functools import reduce
# Define a list of colors
colors = ["red", "blue", "green", "red", "yellow", "blue", "green", "red"]
def get_color_counts(colors):
# Use reduce on the list
return reduce(lambda counts, color:
# For each color, check if it already exists as a key in the counts dictionary
counts.update({color: counts.get(color, 0) + 1}) or counts
# If yes, increment its value by one
# If no, initialize its value to one
# Use update and get methods on the dictionary and return the updated counts dictionary
, colors, {}) # Start with an empty dictionary for the counts
print(get_color_counts(colors)) # {'red': 3, 'blue': 2, 'green': 2, 'yellow': 1}
// Typescript code
const colors: string[] = ["red", "blue", "green", "red", "yellow", "blue", "green", "red"];
function getColorCounts(colors: string[]): Record<string, number> {
// Use the reduce method on the array
return colors.reduce((counts: Record<string, number>, color: string) => {
// For each color, check if it already exists as a key in the counts object
if (counts[color]) {
// If yes, increment its value by one
counts[color] += 1;
} else {
// If no, initialize its value to one
counts[color] = 1;
}
// Return the updated counts object
return counts;
}, {}); // Start with an empty object for the counts
}
console.log(getColorCounts(colors)); // {red: 3, blue: 2, green: 2, yellow: 1}
Those are just a few examples of the powerful functional nature of a reduce function that allows for concise and expressive transformations of iterable data structures. It can be used to implement many other higher-order functions such as map, filter, and find. The reduce function can help simplify complex computations and make code more elegant and efficient.
Top comments (0)