Hone logo
Hone
Problems

Implement a Generic Stack in TypeScript

This challenge requires you to implement a fundamental data structure: a Stack. A Stack follows the Last-In, First-Out (LIFO) principle, meaning the last element added is the first one to be removed. Implementing this as a generic class will allow it to store elements of any data type, making it highly reusable.

Problem Description

You need to create a Stack class in TypeScript that can store elements of any type. This generic Stack class should support the following core operations:

  • push(item: T): Adds an item of type T to the top of the stack.
  • pop(): T | undefined: Removes and returns the item from the top of the stack. If the stack is empty, it should return undefined.
  • peek(): T | undefined: Returns the item from the top of the stack without removing it. If the stack is empty, it should return undefined.
  • isEmpty(): boolean: Returns true if the stack contains no elements, and false otherwise.
  • size(): number: Returns the current number of elements in the stack.

The class should be implemented using TypeScript's generic capabilities, allowing you to specify the type of elements the stack will hold (e.g., Stack<number>, Stack<string>, Stack<UserObject>).

Examples

Example 1: Stack of Numbers

const numberStack = new Stack<number>();
numberStack.push(10);
numberStack.push(20);
console.log(numberStack.peek()); // Output: 20
console.log(numberStack.pop());  // Output: 20
console.log(numberStack.size()); // Output: 1
console.log(numberStack.pop());  // Output: 10
console.log(numberStack.isEmpty()); // Output: true

Explanation: We create a stack for numbers. We push 10, then 20. peek() returns 20 without removing it. pop() removes and returns 20. The size is now 1. Another pop() removes and returns 10, leaving the stack empty. isEmpty() confirms it's empty.

Example 2: Stack of Strings

const stringStack = new Stack<string>();
stringStack.push("apple");
stringStack.push("banana");
console.log(stringStack.pop()); // Output: "banana"
stringStack.push("cherry");
console.log(stringStack.peek()); // Output: "cherry"

Explanation: We create a stack for strings. We push "apple", then "banana". pop() returns "banana". We then push "cherry". peek() returns "cherry".

Example 3: Empty Stack Operations

const emptyStack = new Stack<boolean>();
console.log(emptyStack.isEmpty()); // Output: true
console.log(emptyStack.pop());     // Output: undefined
console.log(emptyStack.peek());    // Output: undefined
console.log(emptyStack.size());    // Output: 0

Explanation: Demonstrates the behavior of pop() and peek() on an empty stack, as well as isEmpty() and size().

Constraints

  • The Stack class must be implemented as a generic class.
  • The underlying storage mechanism for the stack can be an array.
  • All methods should be implemented correctly according to the LIFO principle.
  • The pop() and peek() methods should handle an empty stack gracefully by returning undefined.

Notes

  • Consider how to initialize the stack's internal storage.
  • Think about the return type for pop() and peek() when the stack is empty.
  • TypeScript's generics (<T>) will be crucial for making this class reusable with different data types.
Loading editor...
typescript