Streamlining Your Code with JavaScript's Reduce Method
Tags: javascript, typescript, programming, learning
Published: 2023-06-17 15:22:03

Whether you're just starting out with TypeScript/JavaScript or you're already comfortable with the basics, understanding array methods can significantly enhance your coding efficiency. In this short article, we'll introduce an array method that's often overlooked but incredibly powerful: reduce.

## Understanding the Basics

Typically, to manipulate array data, we'd use methods like filter and map. For example, consider an array of students, where each student has a `name`, `score`, and `class`. Say we want to find the average score of all students in `Class A` who have scored above 50. A traditional approach using filter and map might look like this:

```
// Define student interface
interface Student {
    name: string;
    score: number;
    class: string;
}

// Array of students
const students: Student[] = [
    { name: 'John', score: 80, class: 'Class A' },
    { name: 'Jane', score: 40, class: 'Class A' },
    { name: 'Doe', score: 70, class: 'Class B' },
    { name: 'Smith', score: 60, class: 'Class A' },
];

// Filter the students based on class and score
const filteredStudents = students.filter(student => student.class === 'Class A' && student.score > 50);

// Get the total score
const total = filteredStudents.map(student => student.score).reduce((acc, score) => acc + score, 0);

// Calculate average
const average = total / filteredStudents.length;

console.log(average);

```

This code does the job, but it loops over the array three times. Could we make this more efficient?

## Enter `reduce`

The reduce method can perform the job of both filter and map in just a single pass. It might seem complex at first, but the power it brings to your code is worth the effort.

Here's how you might solve the above problem using reduce:

```
// Define student interface
interface Student {
    name: string;
    score: number;
    class: string;
}

// Define an interface for the data we'll track
interface StudentScoreData {
    totalScore: number;
    studentCount: number;
}

const students: Student[] = [
    { name: 'John', score: 80, class: 'Class A' },
    { name: 'Jane', score: 40, class: 'Class A' },
    { name: 'Doe', score: 70, class: 'Class B' },
    { name: 'Smith', score: 60, class: 'Class A' },
];

// Initialize our tracking data
const initialData: StudentScoreData = { totalScore: 0, studentCount: 0 };

// Use reduce to calculate the total score and student count
const studentScoreData = students.reduce((data, student) => {
    if (student.class === 'Class A' && student.score > 50) {
        return { 
            totalScore: data.totalScore + student.score, 
            studentCount: data.studentCount + 1 
        };
    }
    return data;
}, initialData);

// Calculate average
const averageReduce = studentScoreData.totalScore / studentScoreData.studentCount;

console.log(averageReduce);

```

In this example, we only loop through the array once, increasing efficiency, particularly when dealing with large arrays.

## Wrapping Up

Embracing reduce over filter and map might seem daunting at first, but it's a step worth taking. Not only does it make your code more efficient by reducing the number of iterations, but it also challenges you to think about problems in a slightly different way. 

This article was inspired by this video i saw recently:

{% embed https://www.youtube.com/watch?v=YhLOtIQUrb4&t=1s %}

Happy coding!