UNPKG

standard-data-structures

Version:

A collection of standard data-structures for node and browser

121 lines (120 loc) 2.56 kB
"use strict"; /* tslint:disable no-use-before-declare */ Object.defineProperty(exports, "__esModule", { value: true }); /** * An immutable singly linked list data-structure */ class List { /** * Converts a list into an Array */ get asArray() { return this.fold([], (a, b) => { b.push(a); return b; }); } /** * Creates an empty [[List]] */ static empty() { return new Empty(); } /** * Creates a new [[List]] with the provided elements. */ static of(...element) { let result = List.empty(); for (let i = element.length - 1; i >= 0; i--) { result = result.prepend(element[i]); } return result; } /** * Refer [[ICollection.filter]] */ filter(F) { return this.reverse.fold(List.empty(), (a, l) => (F(a) ? l.prepend(a) : l)); } /** * Reverses the List. */ get reverse() { return this.fold(List.empty(), (a, l) => l.prepend(a)); } /** * Transforms the [[List]] into a value */ fold(seed, ab) { let n = this; let r = seed; while (!n.isEmpty) { r = ab(n.head, r); n = n.tail; } return r; } /** * Transforms the values of the linked list */ map(ab) { let n = this; let r = List.empty(); while (!n.isEmpty) { r = r.prepend(ab(n.head)); n = n.tail; } return r; } /** * Creates a new [[List]] with the provided element in its head. */ prepend(element) { return new Cons(element, this); } /** * Folds the original list into a value of the same type */ reduce(ab) { return this.tail.fold(this.head, ab); } } exports.List = List; /** * Represents an empty list */ class Empty extends List { constructor() { super(...arguments); /** * Is always true */ this.isEmpty = true; } /** * Returns the head of the list */ get head() { throw new Error('Head of an empty list'); } /** * Returns the tail of the list */ get tail() { throw new Error('Tail of an empty list'); } } /** * A non-empty list */ class Cons extends List { constructor(head, tail) { super(); this.head = head; this.tail = tail; /** * Is always false */ this.isEmpty = false; } }