DEV Community

Cover image for JavaScript Array Methods: Sort, Map, Filter, and Reduce
James Ononiwu
James Ononiwu

Posted on

JavaScript Array Methods: Sort, Map, Filter, and Reduce

JavaScript arrays are a cornerstone of modern web development, providing robust tools to manage and manipulate data. Among these tools, the methods sort, map, filter, and reduce stand out for their versatility and power. In this article, we’ll explore these methods in detail, offering explanations and practical examples to deepen your understanding.

1. Array.prototype.sort

The sort method organises the elements of an array based on a specified order. By default, it sorts elements as strings in lexicographical order. However, with a custom comparison function, you can implement advanced sorting logic.

Syntax

array.sort([compareFunction])
Enter fullscreen mode Exit fullscreen mode
  • compareFunction: A function that defines the sort order. It takes two arguments (a, b) and returns:
    • A negative value if a should come before b.
    • Zero if a and b are equivalent.
    • A positive value if a should come after b.

Example: Sorting Numbers in Ascending Order

const numbers = [42, 7, 19, 73, 23];

numbers.sort((a, b) => a - b);

console.log(numbers);
// Output: [7, 19, 23, 42, 73]
Enter fullscreen mode Exit fullscreen mode

Example: Sorting Objects by Property

const books = [
  { title: 'Book A', year: 2001 },
  { title: 'Book B', year: 1998 },
  { title: 'Book C', year: 2015 }
];

books.sort((a, b) => a.year - b.year);

console.log(books);
// Output: [
//   { title: 'Book B', year: 1998 },
//   { title: 'Book A', year: 2001 },
//   { title: 'Book C', year: 2015 }
// ]
Enter fullscreen mode Exit fullscreen mode
  • The sort method modifies the original array.
  • Always provide a compare function for numeric or complex sorting to avoid unexpected results.

2. Array.prototype.map

The map method creates a new array by applying a provided function to each element of the original array. It’s commonly used for transforming data.

Syntax

array.map(callback(element, index, array))
Enter fullscreen mode Exit fullscreen mode
  • callback: A function executed on each element, receiving:
    • The current element.
    • Its index.
    • The original array.

Example: Transforming an Array of Numbers

const numbers = [1, 2, 3, 4, 5];

const squares = numbers.map(num => num ** 2);

console.log(squares);
// Output: [1, 4, 9, 16, 25]
Enter fullscreen mode Exit fullscreen mode

Example: Formatting Data

const users = [
  { firstName: 'John', lastName: 'Doe' },
  { firstName: 'Jane', lastName: 'Smith' }
];

const fullNames = users.map(user => `${user.firstName} ${user.lastName}`);

console.log(fullNames);
// Output: ['John Doe', 'Jane Smith']
Enter fullscreen mode Exit fullscreen mode
  • Working with Sparse Arrays: The map method will execute the callback for every index, including those that are undefined in sparse arrays. For example:
  const sparseArray = [1, , 3]; // Sparse array with a missing element
  const result = sparseArray.map(x => x || 0);
  console.log(result);
  // Output: [1, 0, 3]
Enter fullscreen mode Exit fullscreen mode
  • Preserves Array Structure: Even if some elements are undefined or removed, map preserves the original array structure:
  const array = [10, undefined, 30];
  const doubled = array.map(x => (x !== undefined ? x * 2 : x));
  console.log(doubled);
  // Output: [20, undefined, 60]
Enter fullscreen mode Exit fullscreen mode
  • map is non-destructive; it returns a new array without modifying the original.
  • It’s ideal for transforming data structures. The map method creates a new array by applying a provided function to each element of the original array. It’s commonly used for transforming data.

3. Array.prototype.filter

The filter method creates a new array containing only the elements that satisfy a given condition. It’s often used to extract subsets of data.

Syntax

array.filter(callback(element, index, array))
Enter fullscreen mode Exit fullscreen mode
  • callback: A function that determines whether an element should be included (returns true) or excluded (returns false).

Example: Filtering Even Numbers

const numbers = [1, 2, 3, 4, 5, 6];

const evens = numbers.filter(num => num % 2 === 0);

console.log(evens);
// Output: [2, 4, 6]
Enter fullscreen mode Exit fullscreen mode

Example: Filtering Objects by Condition

const products = [
  { name: 'Laptop', price: 1200 },
  { name: 'Phone', price: 800 },
  { name: 'Tablet', price: 500 }
];

const expensiveProducts = products.filter(product => product.price > 700);

console.log(expensiveProducts);
// Output: [
//   { name: 'Laptop', price: 1200 },
//   { name: 'Phone', price: 800 }
// ]
Enter fullscreen mode Exit fullscreen mode
  • Sparse Arrays: Unlike map, filter skips over missing or undefined elements in sparse arrays entirely. For example:
  const sparseArray = [1, , 3];
  const filtered = sparseArray.filter(x => x !== undefined);
  console.log(filtered);
  // Output: [1, 3]
Enter fullscreen mode Exit fullscreen mode
  • Removing Falsy Values: You can easily remove all falsy values (e.g., false, 0, null, undefined, NaN, "") by using the Boolean constructor as the callback:
  const mixedArray = [0, "hello", false, 42, undefined, "world", null];
  const truthyValues = mixedArray.filter(Boolean);
  console.log(truthyValues);
  // Output: ["hello", 42, "world"]
Enter fullscreen mode Exit fullscreen mode
  • filter does not modify the original array.
  • It’s a powerful tool for extracting relevant data or cleaning up arrays.

4. Array.prototype.reduce

The reduce method applies a function against an accumulator and each element of the array (from left to right) to reduce it to a single value.

Syntax

array.reduce(callback(accumulator, currentValue, index, array), initialValue)
Enter fullscreen mode Exit fullscreen mode
  • callback: A function executed on each element, with parameters:
    • The accumulator.
    • The current element.
    • The index of the current element.
    • The original array.
  • initialValue: The initial value of the accumulator (optional but recommended).

Example: Summing Numbers

const numbers = [10, 20, 30, 40];

const total = numbers.reduce((sum, num) => sum + num, 0);

console.log(total);
// Output: 100
Enter fullscreen mode Exit fullscreen mode

Example: Grouping Data by Property

const people = [
  { name: 'Mike', age: 25 },
  { name: 'Larry', age: 30 },
  { name: 'Charlie', age: 25 }
];

const groupedByAge = people.reduce((acc, person) => {
  if (!acc[person.age]) {
    acc[person.age] = [];
  }
  acc[person.age].push(person.name);
  return acc;
}, {});

console.log(groupedByAge);
// Output: {
//   25: ['Mike', 'Charlie'],
//   30: ['Larry']
// }
Enter fullscreen mode Exit fullscreen mode
  • Flattening Multidimensional Arrays: You can use reduce to flatten nested arrays into a single array:
  const nestedArray = [[1, 2], [3, 4], [5, 6]];
  const flattened = nestedArray.reduce((acc, curr) => acc.concat(curr), []);
  console.log(flattened);
  // Output: [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode
  • Implementing Map/Filter-like Transformations: In some cases, reduce can mimic the behaviour of map or filter while combining multiple transformations in a single pass:
  const numbers = [1, 2, 3, 4, 5];
  const transformed = numbers.reduce((acc, num) => {
    if (num % 2 === 0) {
      acc.push(num * 2); // Double even numbers
    }
    return acc;
  }, []);
  console.log(transformed);
  // Output: [4, 8]
Enter fullscreen mode Exit fullscreen mode
  • reduce is highly flexible, capable of producing arrays, objects, or single values.
  • It’s a powerful tool for custom transformations, data aggregation, and more.
  • Always provide an initial value for better predictability.

Combining Methods

Let’s analyse sales data and determine the total revenue from high-value transactions, considering how combining methods like map, filter, and reduce can be optimised for performance. For example, when working with large datasets, one can avoid multiple iterations by chaining the logic within a single reduce operation. This reduces overhead and can be particularly beneficial when dealing with real-time or resource-constrained scenarios.

const sales = [
  { product: 'Laptop', price: 1500, quantity: 2 },
  { product: 'Phone', price: 800, quantity: 5 },
  { product: 'Tablet', price: 500, quantity: 10 }
];

// Step 1: Calculate revenue for each product
const revenues = sales.map(sale => ({
  product: sale.product,
  revenue: sale.price * sale.quantity
}));

// Step 2: Filter high-revenue products
const highRevenue = revenues.filter(item => item.revenue > 3000);

// Step 3: Calculate total revenue
const totalHighRevenue = highRevenue.reduce((sum, item) => sum + item.revenue, 0);

console.log(revenues);
// Output: [
//   { product: 'Laptop', revenue: 3000 },
//   { product: 'Phone', revenue: 4000 },
//   { product: 'Tablet', revenue: 5000 }
// ]

console.log(highRevenue);
// Output: [
//   { product: 'Phone', revenue: 4000 },
//   { product: 'Tablet', revenue: 5000 }
// ]

console.log(totalHighRevenue);
// Output: 9000
Enter fullscreen mode Exit fullscreen mode

Conclusion

JavaScript’s sort, map, filter, and reduce methods are indispensable for efficient and elegant data manipulation. Understanding their mechanics and applications empowers developers to write cleaner, more maintainable code. Experimenting with these methods will enhance your programming skills!

Top comments (0)