npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

symboltable

v0.0.2

Published

A Symbol Table implementation for JavaScript based on a Red-Black Binary Search Tree.

Downloads

10

Readme

symbol table NPM version

A Generic Symbol Table implementation for JavaScript based on a Red-Black Binary Search Tree. Typed with Flow and exported as ES-modules.

Installation

Simply do: npm install symboltable.

What is it?

It is an ordered symbol table of generic key-value pairs based on a Red-Black Binary Search Tree, inspired by the implementation of Robert Sedgewick and Kevin Wayne.

You don't need a Computer Science degree to know about symbol tables. It is collections of key-value pairs. An object literal in Javascript, for instance, is a symbol table - where only strings can be used as keys. In Python, a Dictionary is a Symbol table.

In ES2015, the Map collection type came to JavaScript which is an actual, proper Symbol table where the keys can be of any type.

This is a powerful implementation which enables you to do all operations in *O(log(N)) time:

Search: O(log(N))

Insert: O(log(N))

Delete: O(log(N))

What this means is that you can put, get and delete incredibly fast for even large collections. Because it is ordered, it also enables you to easily get the minimum and maximum values fast as well as other cool things such as the ceiling(), floor(), select() and rank() operations which will be described in the documentation below.

Example

import {SymbolTable} from "symboltable";

const map = new SymbolTable();

for (let child of Array.from(document.body.children)) {
	map.put(child.offsetTop, child);
}
// Produces a map between node positions and nodes.

Changelog:

v0.02:

  • Fixed a few typing errors.

v0.01:

  • First release!

Usage

Import it in your project like this:

import {SymbolTable, FullSymbolTable} from "symboltable"; // (standard) Transpiled to ES5.
// or

import {SymbolTable, FullSymbolTable} from "symboltable/native" // Transpiled to ES5, native ES-modules.
// or

import {SymbolTable, FullSymbolTable} from "symboltable/typed" // Flow typings, ES-modules.

Documentation

The Symbol Table comes in two flavors:

  • SymbolTable - The standard version. Has the basic and most foundational features.

  • FullSymbolTable - An extended version with the addition of floor(), ceiling(), rank(), select(), deleteMin() and deleteMax() operations.

Types

// All types in Javascript inherits the 'valueOf()' method from Object
// And can be extended. It is used to compare the value with other objects
// Of the same type. For instance, when comparing numbers, we know that
// 1 < 2 and 1 > 0. With custom types, we can override the 'valueOf' method
// To enable comparisons of object instances with the '<', '==' and '>' operators.
interface Comparable {
	valueOf(): number;
}

SymbolTable<Key:Comparable, Value>

The standard version has the following getters and methods:

size

Returns the number of key-value pairs in this symbol table.

Signature:

get size (): number

Returns:

number - The size of the collection.

Example

let map = new SymbolTable();
map.size; // Returns 0;
map.put("a", 0);
map.size; // Returns 1;

isEmpty

Returns true if the symbol table is empty.

Signature:

get isEmpty (): boolean

Returns:

boolean - Whether or not the symbol table is empty.

Example

let map = new SymbolTable();
map.isEmpty; // Returns true;
map.put("a", 0);
map.isEmpty; // Returns false;

min

Returns the smallest key in the symbol table.

Signature:

get min (): Key

Returns:

Key - The smallest key in the collection.

Throws:

  • ReferenceError - If the symbol table is empty.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");
map.min; // Returns 1;

max

Returns the largest key in the symbol table.

Signature:

get max (): Key

Returns:

Key - The largest key in the collection.

Throws:

  • ReferenceError - If the symbol table is empty.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");
map.max; // Returns 2;

#get()

Gets the value associated with the given key, if any.

Signature:

get (key: Key): ?Value

Arguments:

  • key: Key - The key to get the associated value for.

Returns:

?Value - The associated value, if any.

Throws:

  • ReferenceError - If the given argument is null or undefined.
  • TypeError - If the given key is of a different type than the existing keys.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.get(2);     // returns "b";
map.get(null);  // Throws a 'ReferenceError'.
map.get(false); // Throws a 'TypeError'.

#contains()

Returns true if the symbol table contains the given key.

Signature:

contains (key: Key): boolean

Arguments:

  • key: Key - The key to check for the existence of in the collection.

Returns:

boolean - Whether or not the key exists in the symbol table.

Throws:

  • ReferenceError - If the given argument is null or undefined.
  • TypeError - If the given key is of a different type than the existing keys.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.contains(2);     // returns true;
map.contains(3);     // returns false;
map.contains(null);  // Throws a 'ReferenceError'.
map.contains(false); // Throws a 'TypeError'.

#put()

Inserts the specified key-value pair into the symbol table, overwriting the old value with the new value if the symbol table already contains the specified key. Deletes the specified key (and its associated value) from this symbol table if the specified value is null.

Signature:

put (key: Key, value: Value): void

Arguments:

  • key: Key - The key to insert in the symbol table.

  • value: Value - The value to associate with the key.

Returns:

void

Throws:

  • ReferenceError - If the given key is null or undefined.
  • TypeError - If the given key is of a different type than the existing keys.

Example

let map = new SymbolTable();
map.put(2, "b"); // Puts the key 2 in the symbol table and associates it with the value 'b'.
map.put(1, "a"); // Puts the key 1 in the symbol table and associates it with the value 'a'.

map.put(2, "c"); // Updates the value associated with the key 2.
map.put(1, null); // Deletes the key-value pair associated with the key 1.

map.put("a", "d");  // Throws a 'TypeError', existing keys are of a different type.
map.put(null, "e"); // Throws a 'ReferenceError', keys can not be null or undefined.

#clear()

Empties the symbol table.

Signature:

clear (): void

Returns:

void

Example

let map = new SymbolTable();
map.put(2, "b");
map.size; // Returns 1.

map.clear();
map.size; // Returns 0 - The call to clear() emptied the collection.

#delete()

Removes the specified key and its associated value from this symbol table (if the key is in this symbol table).

Signature:

delete (key: Key): void

Arguments:

  • key: Key - The key to delete from the symbol table.

Returns:

void

Throws:

  • ReferenceError - If the given key is null or undefined.
  • TypeError - If the given key is of a different type than the existing keys.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.delete(2); // Removes the key 2 and the associated value 'b' from the symbol table.

map.delete("a");    // Throws a 'TypeError', existing keys are of a different type.
map.delete(null);   // Throws a 'ReferenceError', keys can not be null or undefined.

keys

Returns all keys in the symbol table as an ordered array.

Signature:

get keys (): Array<Key>

Returns:

Array<Key> - An ordered array of keys.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.keys; // Returns [1, 2]

values

Returns all values in the symbol table as an array.

Signature:

get values (): Array<Value>

Returns:

Array<Value> - An array of values.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.values; // Returns ["a", "b"]

entries

Returns all values and entries in the symbol table as an array of tuples.

Signature:

get entries (): Array<[Value, Key]>

Returns:

Array<[Value, Key]> - An ordered array of tuples of values and keys.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.entries; // Returns [ ["a", 1], ["b", 2] ]

#forEach()

Calls the given handler for all entries.

Signature:

forEach (handler: (value: Value, key: Key) => void): void

Arguments:

  • handler: (value: Value, key: Key) => void - A callback function that will be called for each item in the collection with the value as the first argument and the key as the second.

Returns:

void

Throws:

  • ReferenceError - If the given handler is not defined.

Example

let map = new SymbolTable();
map.put(2, "b");
map.put(1, "a");

map.forEach((value, key) => console.log(value, key)); // Prints all values and keys out to the console.

FullSymbolTable<Key:Comparable, Value>

The extended version has the following additional methods:

#deleteMin()

Removes the smallest key and associated value from the symbol table.

Signature:

deleteMin (): void

Returns:

void

Throws:

  • ReferenceError - If the symbol table is empty.

Example

let map = new FullSymbolTable();
map.put(2, "b");
map.put(1, "a");

map.deleteMin(); // Deletes the key 1 and the associated value from the symbol table.

#deleteMax()

Removes the largest key and associated value from the symbol table.

Signature:

deleteMax (): void

Returns:

void

Throws:

  • ReferenceError - If the symbol table is empty.

Example

let map = new FullSymbolTable();
map.put(2, "b");
map.put(1, "a");

map.deleteMax(); // Deletes the key 2 and the associated value from the symbol table.

#floor()

Returns the largest key in the symbol table less than or equal to the given key.

Signature:

floor (key: Key): ?Key

Arguments:

  • key: Key - The key for which to find the largest key that is equal to or less than it.

Returns:

?Key - The largest key that is equal to or less than the given key, if any.

Throws:

  • ReferenceError - If the provided argument is null or undefined

  • ReferenceError - If the symbol table is empty.

  • TypeError - If the provided key is of another type than the existing keys.

Example

let map = new FullSymbolTable();
map.put(2, "b");
map.put(1, "a");

map.floor(1.8); // Returns the key 1.
map.floor(2);   // Returns the key 2.
map.floor(0.9); // Returns null, no keys are smaller than or equal to 0.9

#ceiling()

Returns the smallest key in the symbol table greater than or equal to the given key.

Signature:

ceiling (key: Key): ?Key

Arguments:

  • key: Key - The key for which to find the smallest key that is equal to or greater than it.

Returns:

?Key - The smallest key that is equal to or greater than the given key, if any.

Throws:

  • ReferenceError - If the provided argument is null or undefined

  • ReferenceError - If the symbol table is empty.

  • TypeError - If the provided key is of another type than the existing keys.

Example

let map = new FullSymbolTable();
map.put(2, "b");
map.put(1, "a");

map.ceiling(1.8); // Returns the key 2.
map.ceiling(1);   // Returns the key 1.
map.floor(2.2);   // Returns null, no keys are equal to or greater than 2.2.

#select()

Returns the kth smallest key in the symbol table where k = position. For instance, given 5 as input, it will return the 5th smallest key in the symbol table.

Signature:

select (k: number): Key

Arguments:

  • k: number - The kth position to match with a key ordered from low to high.

Returns:

?Key - The kth smallest key

Throws:

  • RangeError - If k is out of bounds.

  • TypeError - If k is not of type 'number'.

Example

let map = new FullSymbolTable();
map.put(0, "a");
map.put(1, "b");
map.put(2, "c");

map.select(1); // Returns 1, only 1 key is less than it.

#rank()

Returns the number of keys in the symbol table strictly less than the given key.

Signature:

rank (key: Key): number

Arguments:

  • key: Key - The key.

Returns:

number - The number of keys in the symbol table strictly less than the given key.

Throws:

  • ReferenceError - If the provided key is null or undefined.

  • TypeError - If the provided key is not of the same type as any existing keys.

Example

let map = new FullSymbolTable();
map.put(0, "a");
map.put(1, "b");
map.put(2, "c");

map.rank(2); // Returns 2, only 0 and 1 is strictly less than the given key.