Class Stack<E, R>

LIFO stack with array storage and optional record→element conversion.

Time O(1), Space O(1)

// Balanced Parentheses or Brackets
type ValidCharacters = ')' | '(' | ']' | '[' | '}' | '{';

const stack = new Stack<string>();
const input: ValidCharacters[] = '[({})]'.split('') as ValidCharacters[];
const matches: { [key in ValidCharacters]?: ValidCharacters } = { ')': '(', ']': '[', '}': '{' };
for (const char of input) {
if ('([{'.includes(char)) {
stack.push(char);
} else if (')]}'.includes(char)) {
if (stack.pop() !== matches[char]) {
fail('Parentheses are not balanced');
}
}
}
console.log(stack.isEmpty()); // true
// Expression Evaluation and Conversion
const stack = new Stack<number>();
const expression = [5, 3, '+']; // Equivalent to 5 + 3
expression.forEach(token => {
if (typeof token === 'number') {
stack.push(token);
} else {
const b = stack.pop()!;
const a = stack.pop()!;
stack.push(token === '+' ? a + b : 0); // Only handling '+' here
}
});
console.log(stack.pop()); // 8
// Depth-First Search (DFS)
const stack = new Stack<number>();
const graph: { [key in number]: number[] } = { 1: [2, 3], 2: [4], 3: [5], 4: [], 5: [] };
const visited: number[] = [];
stack.push(1);
while (!stack.isEmpty()) {
const node = stack.pop()!;
if (!visited.includes(node)) {
visited.push(node);
graph[node].forEach(neighbor => stack.push(neighbor));
}
}
console.log(visited); // [1, 3, 5, 2, 4]
// Backtracking Algorithms
const stack = new Stack<[number, number]>();
const maze = [
['S', ' ', 'X'],
['X', ' ', 'X'],
[' ', ' ', 'E']
];
const start: [number, number] = [0, 0];
const end = [2, 2];
const directions = [
[0, 1], // To the right
[1, 0], // down
[0, -1], // left
[-1, 0] // up
];

const visited = new Set<string>(); // Used to record visited nodes
stack.push(start);
const path: number[][] = [];

while (!stack.isEmpty()) {
const [x, y] = stack.pop()!;
if (visited.has(`${x},${y}`)) continue; // Skip already visited nodes
visited.add(`${x},${y}`);

path.push([x, y]);

if (x === end[0] && y === end[1]) {
break; // Find the end point and exit
}

for (const [dx, dy] of directions) {
const nx = x + dx;
const ny = y + dy;
if (
maze[nx]?.[ny] === ' ' || // feasible path
maze[nx]?.[ny] === 'E' // destination
) {
stack.push([nx, ny]);
}
}
}

expect(path).toContainEqual(end);
// Function Call Stack
const functionStack = new Stack<string>();
functionStack.push('main');
functionStack.push('foo');
functionStack.push('bar');
console.log(functionStack.pop()); // 'bar'
console.log(functionStack.pop()); // 'foo'
console.log(functionStack.pop()); // 'main'
// Simplify File Paths
const stack = new Stack<string>();
const path = '/a/./b/../../c';
path.split('/').forEach(segment => {
if (segment === '..') stack.pop();
else if (segment && segment !== '.') stack.push(segment);
});
console.log(stack.elements.join('/')); // 'c'
// Stock Span Problem
const stack = new Stack<number>();
const prices = [100, 80, 60, 70, 60, 75, 85];
const spans: number[] = [];
prices.forEach((price, i) => {
while (!stack.isEmpty() && prices[stack.peek()!] <= price) {
stack.pop();
}
spans.push(stack.isEmpty() ? i + 1 : i - stack.peek()!);
stack.push(i);
});
console.log(spans); // [1, 1, 1, 2, 1, 4, 6]

Type Parameters

  • E = any
  • R = any
    1. Last In, First Out (LIFO): The core characteristic of a stack is its last in, first out nature, meaning the last element added to the stack will be the first to be removed.
    2. Uses: Stacks are commonly used for managing a series of tasks or elements that need to be processed in a last in, first out manner. They are widely used in various scenarios, such as in function calls in programming languages, evaluation of arithmetic expressions, and backtracking algorithms.
    3. Performance: Stack operations are typically O(1) in time complexity, meaning that regardless of the stack's size, adding, removing, and viewing the top element are very fast operations.
    4. Function Calls: In most modern programming languages, the records of function calls are managed through a stack. When a function is called, its record (including parameters, local variables, and return address) is 'pushed' into the stack. When the function returns, its record is 'popped' from the stack.
    5. Expression Evaluation: Used for the evaluation of arithmetic or logical expressions, especially when dealing with parenthesis matching and operator precedence.
    6. Backtracking Algorithms: In problems where multiple branches need to be explored but only one branch can be explored at a time, stacks can be used to save the state at each branching point.

Hierarchy (view full)

Constructors

  • Create a Stack and optionally bulk-push elements.

    Type Parameters

    • E = any
    • R = any

    Parameters

    • Optionalelements: Iterable<E, any, any> | Iterable<R, any, any> = []

      Iterable of elements (or raw records if toElementFn is set).

    • Optionaloptions: StackOptions<E, R>

      Options such as toElementFn and equality function.

    Returns Stack<E, R>

    New Stack instance.

    Time O(N), Space O(N)

Properties

_toElementFn?: ((rawElement: R) => E)

The converter used to transform a raw element (R) into a public element (E).

Time O(1), Space O(1).

Accessors

  • get toElementFn(): undefined | ((rawElement: R) => E)
  • Exposes the current toElementFn, if configured.

    Returns undefined | ((rawElement: R) => E)

    The converter function or undefined when not set.

    Time O(1), Space O(1).

Methods

  • (Protected) Create an empty instance of the same concrete class.

    Parameters

    • Optionaloptions: StackOptions<E, R>

      Options forwarded to the constructor.

    Returns this

    An empty like-kind stack instance.

    Time O(1), Space O(1)

  • (Protected) Create a like-kind stack and seed it from an iterable.

    Type Parameters

    • T = E
    • RR = R

    Parameters

    • Optionalelements: Iterable<T, any, any> | Iterable<RR, any, any> = []

      Iterable used to seed the new stack.

    • Optionaloptions: StackOptions<T, RR>

      Options forwarded to the constructor.

    Returns Stack<T, RR>

    A like-kind Stack instance.

    Time O(N), Space O(N)

  • (Protected) Find the index of a target element using the equality function.

    Parameters

    • target: E

      Element to search for.

    Returns number

    Index or -1 if not found.

    Time O(N), Space O(1)

  • Returns an iterator over the structure's elements.

    Parameters

    • Rest...args: unknown[]

      Optional iterator arguments forwarded to the internal iterator.

    Returns IterableIterator<E, any, any>

    An IterableIterator<E> that yields the elements in traversal order.

    Producing the iterator is O(1); consuming the entire iterator is Time O(n) with O(1) extra space.

  • Delete the first occurrence of a specific element.

    Parameters

    • element: E

      Element to remove (using the configured equality).

    Returns boolean

    True if an element was removed.

    Time O(N), Space O(1)

  • Delete the element at an index.

    Parameters

    • index: number

      Zero-based index from the bottom.

    Returns boolean

    True if removed.

    Time O(N), Space O(1)

  • Delete the first element that satisfies a predicate.

    Parameters

    • predicate: ((value: E, index: number, stack: this) => boolean)

      Function (value, index, stack) → boolean to decide deletion.

        • (value, index, stack): boolean
        • Parameters

          • value: E
          • index: number
          • stack: this

          Returns boolean

    Returns boolean

    True if a match was removed.

    Time O(N), Space O(1)

  • Tests whether all elements satisfy the predicate.

    Parameters

    • predicate: ElementCallback<E, R, boolean>

      Function invoked for each element with signature (value, index, self).

    • OptionalthisArg: unknown

      Optional this binding for the predicate.

    Returns boolean

    true if every element passes; otherwise false.

    Time O(n) in the worst case; may exit early when the first failure is found. Space O(1).

  • Filter elements into a new stack of the same class.

    Parameters

    • predicate: ElementCallback<E, R, boolean>

      Predicate (value, index, stack) → boolean to keep value.

    • OptionalthisArg: unknown

      Value for this inside the predicate.

    Returns this

    A new stack with kept values.

    Time O(N), Space O(N)

  • Finds the first element that satisfies the predicate and returns it.

    Finds the first element of type S (a subtype of E) that satisfies the predicate and returns it.

    Type Parameters

    • S

    Parameters

    • predicate: ElementCallback<E, R, S>

      Type-guard predicate: (value, index, self) => value is S.

    • OptionalthisArg: unknown

      Optional this binding for the predicate.

    Returns undefined | S

    The matched element typed as S, or undefined if not found.

    Time O(n) in the worst case; may exit early on the first match. Space O(1).

  • Invokes a callback for each element in iteration order.

    Parameters

    • callbackfn: ElementCallback<E, R, void>

      Function invoked per element with signature (value, index, self).

    • OptionalthisArg: unknown

      Optional this binding for the callback.

    Returns void

    void.

    Time O(n), Space O(1).

  • Map values into a new stack (possibly different element type).

    Type Parameters

    • EM
    • RM

    Parameters

    • callback: ElementCallback<E, R, EM>

      Mapping function (value, index, stack) → newElement.

    • Optionaloptions: IterableElementBaseOptions<EM, RM>

      Options for the output stack (e.g., toElementFn).

    • OptionalthisArg: unknown

      Value for this inside the callback.

    Returns Stack<EM, RM>

    A new Stack with mapped elements.

    Time O(N), Space O(N)

  • Map values into a new stack of the same element type.

    Parameters

    • callback: ElementCallback<E, R, E>

      Mapping function (value, index, stack) → newValue.

    • OptionalthisArg: unknown

      Value for this inside the callback.

    Returns this

    A new stack with mapped values.

    Time O(N), Space O(N)

  • Get the top element without removing it.

    Returns undefined | E

    Top element or undefined.

    Time O(1), Space O(1)

  • Push one element onto the top.

    Parameters

    • element: E

      Element to push.

    Returns boolean

    True when pushed.

    Time O(1), Space O(1)

  • Push many elements from an iterable.

    Parameters

    • elements: Iterable<E, any, any> | Iterable<R, any, any>

      Iterable of elements (or raw records if toElementFn is set).

    Returns boolean[]

    Array of per-element success flags.

    Time O(N), Space O(1)

  • Set the equality comparator used by delete/search operations.

    Parameters

    • equals: ((a: E, b: E) => boolean)

      Equality predicate (a, b) → boolean.

        • (a, b): boolean
        • Parameters

          Returns boolean

    Returns this

    This stack.

    Time O(1), Space O(1)

  • Tests whether at least one element satisfies the predicate.

    Parameters

    • predicate: ElementCallback<E, R, boolean>

      Function invoked for each element with signature (value, index, self).

    • OptionalthisArg: unknown

      Optional this binding for the predicate.

    Returns boolean

    true if any element passes; otherwise false.

    Time O(n) in the worst case; may exit early on first success. Space O(1).

  • Create a stack from an array of elements.

    Type Parameters

    • E
    • R = any

    Parameters

    • this: Object

      The constructor (subclass) to instantiate.

    • elements: E[]

      Array of elements to push in order.

    • Optionaloptions: StackOptions<E, R>

      Options forwarded to the constructor.

    Returns any

    A new Stack populated from the array.

    Time O(N), Space O(N)