Lesson 2
Exploring Sets in TypeScript
Introduction

Welcome to our TypeScript Sets lesson! In TypeScript, sets are collections that can only store unique elements, ensuring no duplicates exist. This is particularly beneficial when you want to preserve unique items in a collection. The TypeScript type system adds an additional layer of safety by providing type annotations, which complement the inherent uniqueness sets offer.

In this lesson, you'll learn how to create and manipulate sets, explore their advantages, and understand how they can enhance performance with TypeScript's static typing. Let's dive into the world of sets with TypeScript!

Creating and Manipulating Sets

Let's begin by creating a set in TypeScript. You can create a set using the Set() constructor, similar to arrays, with type safety benefits.

TypeScript
1// Creating a set and printing it 2let mySet: Set<number> = new Set([1, 2, 3, 4, 5, 5, 5]); // Duplicates will be omitted 3console.log(mySet); // Output: Set(5) { 1, 2, 3, 4, 5 }

TypeScript provides methods to manipulate sets, including add(), has(), delete(), and clear().

TypeScript
1// Adding an element 2mySet.add(6); // mySet is now Set { 1, 2, 3, 4, 5, 6 } 3 4console.log(mySet.has(1)); // Output: true, as `mySet` includes an element 1 5 6// Removing an element 7mySet.delete(1); // mySet becomes Set { 2, 3, 4, 5, 6 } 8 9console.log(mySet.has(1)); // Output: false, as `mySet` doesn't include 1 anymore 10 11// Clearing the set 12mySet.clear(); // mySet becomes an empty set 13console.log(mySet); // Output: Set(0) {}
  • add(): Adds a specified element to the set. Sets are unordered collections, which means that elements do not have a specific sequence. The element is added to the set if it's not already present.
  • has(): Checks if the specified element exists in the set.
  • delete(): Removes a specified element from the set.
  • clear(): Removes all elements from the set.
Set Operations

Though TypeScript does not provide built-in methods for operations like union, intersection, and difference directly on sets, these can be implemented using standard TypeScript syntax.

TypeScript
1let set1: Set<number> = new Set([1, 2, 3, 4]); // First set 2let set2: Set<number> = new Set([3, 4, 5, 6]); // Second set 3 4// Set union 5let union: Set<number> = new Set([...set1, ...set2]); 6console.log(union); // Output: Set(6) { 1, 2, 3, 4, 5, 6 } 7 8// Set intersection 9let intersection: Set<number> = new Set([...set1].filter(x => set2.has(x))); 10console.log(intersection); // Output: Set(2) { 3, 4 } 11 12// Set difference 13let difference: Set<number> = new Set([...set1].filter(x => !set2.has(x))); 14console.log(difference); // Output: Set(2) { 1, 2 }
  • union: This operation combines elements from both set1 and set2, excluding any duplicates. The statement new Set([...set1, ...set2]) first spreads the elements of both sets into an array. Using the Set constructor on this array ensures any duplicate elements are automatically removed, resulting in a set containing {1, 2, 3, 4, 5, 6}.
  • intersection: The intersection operation returns elements common to both set1 and set2. The filter() method iterates over elements of set1, and set2.has(x) checks if each element from set1 also exists in set2. A new set is constructed with these common elements, giving us {3, 4}.
  • difference: The difference operation results in elements that exist in set1 but not in set2. Again, filter() is used to select elements from set1 that are not found in set2 using !set2.has(x). A new set is formed with these elements, which results in {1, 2} for set1.
Performance Benefits of Sets

Sets in TypeScript are built on hash tables, which enable efficient operations like membership tests. This underlying data structure allows sets to determine the presence of an element in constant time, providing significant performance advantages over arrays, which rely on linear searches for such operations. Let's see this in action with a comparison of sets and arrays for membership testing:

TypeScript
1let mySet: Set<number> = new Set(Array.from({length: 10000000}, (_, i) => i)); // A set of 10^7 elements 2console.time("Set"); 3console.log(mySet.has(9999999)); // Sets find the number swiftly 4console.timeEnd("Set"); 5 6let myArray: number[] = Array.from({length: 10000000}, (_, i) => i); // An array with the same elements and order 7console.time("Array"); 8console.log(myArray.includes(9999999)); // Arrays take longer to find the number 9console.timeEnd("Array"); 10 11// Output: 12// true 13// Set: 4.388ms 14// true 15// Array: 30.856ms 16 17// Note: The exact time output can vary depending on the system and environment, but generally, Set operations are faster than Array operations for lookups. 18
  • Membership Test with Set: Due to hash tables, sets can verify membership in constant time, offering quick lookup times. Adding TypeScript's type annotations provides further advantages in terms of code safety and predictability.
  • Membership Test with Array: Arrays use a linear search for membership testing, leading to longer lookup times as the array size grows.
Lesson Summary

Congratulations! You've explored creating and manipulating sets, performing set operations, and understanding performance benefits in TypeScript.

Remember to leverage TypeScript's type system for safer and more predictable code. Practicing these concepts will help you master the use of sets in a TypeScript environment. Happy coding!

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