Lesson 4
Data Aggregation Techniques in TypeScript
Introduction to Data Aggregation Methods in TypeScript

Welcome to today's lesson! Our topic for the day is data aggregation, a crucial aspect of data analysis. Like summarizing a massive book into key points, data aggregation summarizes large amounts of data into important highlights.

By the end of this lesson, you'll be equipped with several aggregation methods to summarize data streams in TypeScript. Let's get started!

Basic Aggregation using Built-in Functions

Let's say we have an array of numbers denoting the ages of a group of people:

TypeScript
1const ages: number[] = [21, 23, 20, 25, 22, 27, 24, 22, 25, 22, 23, 22];

Common questions we might ask are: How many people are in the group? What's their total age? Who's the youngest and the oldest? TypeScript's type annotations, combined with methods like length, reduce, Math.min, and Math.max, have our answers:

TypeScript
1const numPeople: number = ages.length; // Number of people (12) 2const totalAges: number = ages.reduce((a, b) => a + b, 0); // Total age (276) 3const youngestAge: number = Math.min(...ages); // Youngest age (20) 4const oldestAge: number = Math.max(...ages); // Oldest age (27) 5 6// Use reduce and length to find the average age 7const averageAge: number = totalAges / numPeople; // Result: 23 8 9// Use Math.max() and Math.min() to find the range of ages 10const ageRange: number = oldestAge - youngestAge; // Result: 7

In this code snippet, we utilize several built-in functions for basic aggregation tasks. The length property is used to count the number of elements in the ages array, giving us the total number of people. The reduce function used here to sum the ages, will be discussed in detail later in this lesson. For now, it is important to note that reduce accumulates elements of an array into a single value. Next, Math.min and Math.max help determine the youngest and oldest ages by finding the minimum and maximum values in the array, respectively. Finally, the average age is calculated by dividing the total age by the number of people, and the age range is obtained by subtracting the youngest age from the oldest age. These operations, along with TypeScript’s type annotations, ensure both code clarity and type safety.

Advanced Aggregation using For and While Loops

For deeper analysis, such as finding the mode or most frequent age, we can use for and while loops effectively:

TypeScript
1const ages: number[] = [21, 23, 20, 25, 22, 27, 24, 22, 25, 22, 23, 22]; 2 3// Initialize a Map to store the frequency of each age 4const frequencies = new Map<number, number>(); 5 6// Use a for loop to populate frequencies 7for (const age of ages) { 8 frequencies.set(age, (frequencies.get(age) || 0) + 1); 9} 10 11// Find the age with the max frequency 12let maxFreq: number = 0; 13let modeAge: number = -1; 14for (const [age, freq] of frequencies) { 15 if (freq > maxFreq) { 16 maxFreq = freq; 17 modeAge = age; 18 } 19} 20 21console.log('Max frequency:', maxFreq); // Max frequency: 4 22console.log('Mode age:', modeAge); // Mode age: 22

The code calculates the mode (the most frequent age) from an array of ages.

The line frequencies.set(age, (frequencies.get(age) || 0) + 1); updates the frequency of each age in the frequencies Map. Here’s a breakdown:

  • frequencies.get(age) retrieves the current frequency of the age from the Map.
  • If the age is not found (i.e., frequencies.get(age) is undefined), the expression (frequencies.get(age) || 0) ensures it starts at 0.
  • Then, + 1 increments the frequency by 1 for each occurrence of the age.
  • Finally, frequencies.set(age, ...) updates the Map with the new frequency.

The rest of the code finds the age with the highest frequency (mode) by iterating through the Map.

While loops can also be used similarly for complex tasks.

Utilizing the 'reduce' Function for Aggregation

Next, let's explore the reduce function, a powerful tool for performing complex aggregations with type annotations for safety. The reduce function runs a callback for each element in an array, using two parameters: an accumulator, which stores the ongoing result, and the current element being processed. This function starts with an initial value for the accumulator and iteratively combines each element with the accumulator to produce a single cumulative value.

TypeScript
1const ages: number[] = [21, 23, 20, 25, 22]; 2const product: number = ages.reduce((a, b) => a * b, 1); // 1 is the start value for the calculation 3// This performs the following calculation: (((((1 * 21) * 23) * 20) * 25) * 22) 4console.log(product); // Output: 5313000

We can also use reduce to accomplish more challenging tasks. Consider, for instance, the problem of separately computing the sums of even numbers and odd numbers in the ages array.

TypeScript
1const ages: number[] = [21, 23, 20, 25, 22]; 2type SumResult = { evens: number; odds: number }; 3 4const ages: number[] = [21, 23, 20, 25, 22]; 5const sums = ages.reduce<SumResult>((acc, curr) => { 6 if (curr % 2 === 0) { 7 acc.evens += curr; 8 } else { 9 acc.odds += curr; 10 } 11 return acc; 12}, { evens: 0, odds: 0 }); 13 14console.log(sums); // Output: {evens: 42, odds: 69}

In this example, elements of the array are summed into even and odd categories. Using TypeScript's type annotations for the accumulator object ensures clarity and prevents errors.

Lesson Summary and Practice

Fantastic! You've just learned how to use basic and advanced data aggregation methods in TypeScript, including the reduce function! With type annotations, these techniques are pivotal in data analysis, offering both safety and clarity. Now, get ready for the practical tasks lined up next. They'll reinforce the skills you've just gained. Remember, the more you practice, the better you become. Good luck with your practice!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.