DEV Community

Shashank Trivedi
Shashank Trivedi

Posted on

Function composition pattern in Javascript

const compose = (...fns) => (data) => fns.reduce((acc, fn) => fn(acc), data);
// This is not just a single line of code it is called the functional // composition pattern
Enter fullscreen mode Exit fullscreen mode

Let me deep down

Scenario

Imagine you're building an e-commerce platform where you need to process a series of actions on a list of product prices. The tasks you need to perform are:

  1. Filter out any products that are under $20.
  2. Apply a 10% discount on the remaining products.
  3. Calculate the total price of the discounted products.

Breaking It Down:

We can break this logic into three simple functions:

  • Filter products by price.

  • Apply discount.

  • Sum the prices.

Each function performs a single task, and when combined (or "composed"), they form the final solution.

Step -1

// Filters out products below $20
const filterByPrice = (products) => products.filter(product => product.price >= 20);

// Applies a 10% discount to each product
const applyDiscount = (products) => products.map(product => ({
  ...product,
  price: product.price * 0.9, // 10% discount
}));

// Sums up the total price of all products
const calculateTotal = (products) => products.reduce((total, product) => total + product.price, 0);

Enter fullscreen mode Exit fullscreen mode

Each function is responsible for a specific part of the processing pipeline. The functions are pure (they don’t mutate the input) and easily composable.

Step-2

const compose = (...fns) => (data) => fns.reduce((acc, fn) => fn(acc), data);

Enter fullscreen mode Exit fullscreen mode

Here, the compose function takes a series of functions (...fns) and returns a function that executes these functions from left to right, passing the result of one function as input to the next.

Step 3: Use the composed function

Now, let’s create a composed function for the product price transformation and use it with a list of products.

const processPrices = compose(
  filterByPrice,
  applyDiscount,
  calculateTotal
);

// Example product list
const products = [
  { id: 1, name: "Laptop", price: 1000 },
  { id: 2, name: "Mouse", price: 15 },
  { id: 3, name: "Keyboard", price: 25 },
  { id: 4, name: "Monitor", price: 200 }
];

// Process the prices
const totalPrice = processPrices(products);
console.log(totalPrice); // Output: 1102.5

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Filter By Price: First, we filter out the products that are less than $20 (Mouse in this case).

  • Apply Discount: Then, we apply a 10% discount to the remaining products (Laptop, Keyboard, and Monitor).

  • Calculate Total: Finally, we sum the prices of the discounted products to get the total price.

This process is much cleaner and more maintainable compared to doing everything in one large, complex function. Each function is reusable, and the flow is easy to understand.

Top comments (0)