Welcome to the documentation of the Standard Collections Library for JavaScript.
This package is available on NPM:
npm install scl
Use the links on the left/right to browse through the provided collections. Each collection describes how you should import it.
This module also exports some generics you can use to define functions that work on a specific category of collections. For example, to have a function that fills any kind of collection with numbers, you could do the following:
import { Collection } from "scl"
function fill(collection: Collection<number>) {
collection.add(1)
collection.add(2)
collection.add(3)
collection.add(4)
collection.add(5)
}
The following table lists what kind of collections are available and how they relate to one another:
Container | Type | Unique | Order |
---|---|---|---|
Bag | T | No | No |
Set | T | Yes | No |
Sequence | T | No | Yes |
QueueLike | T | No | Yes |
Dict | Pair<K, V> | Yes | No |
MultiDict | Pair<K, V> | No | No |
If you found a problem with the documentation, you can open an issue on GitHub. If you like this library, don't forget to star the repository and leave a thank-you note somewhere in your project.
Using the priority queue to sort some tasks on importance
import { PriorityQueue } from "scl"
interface Task {
priority: number
description: string
}
const tasks = new PriorityQueue<Task>({
compare: (a, b) => a.priority < b.priority
})
tasks.add({ description: 'Do the dishes', priority: 5 })
tasks.add({ description: 'Buy food', priority: 1 })
tasks.add({ description: 'Play some games', priority: 52 })
tasks.add({ description: 'Go for a walk', priority: 10 })
tasks.add({ description: 'Program like crazy', priority: 20 })
// Take the most important task from the queue
const buyFood = tasks.pop();
// See what the next task looks like without removing it
const doTheDishes = tasks.peek()
console.log('I should do the remaining tasks in the following order:');
for (const task of tasks) {
console.log(`- ${task.description}`);
}
This will output the following text:
I should do the remaining tasks in the following order: - Do the dishes - Go for a walk - Program like crazy - Play some games
Sorting and querying a list of people based on their age
import { TreeIndex } from "scl"
interface Person {
name: string;
email: string;
age: number;
}
const people = new TreeIndex<Person, number>([
{
name: 'Bob',
email: 'thebobman@gmail.com',
age: 45,
},
{
name: 'Fred',
email: 'fred@outlook.com',
age: 33,
},
{
name: 'Lisa',
email: 'lisa.turner@gmail.com',
age: 37,
}
]);
// Lisa is the oldest person who is at the very most 40 years old.
const lisa = people.getGreatestLowerBound(40);
// Bob is the youngest person older than Lisa
const bob = lisa.next();
// No one is older than Bob
assert(bob.next() === null);
Storing many different translations in the same dictionary
import { TreeMultiDict } from "scl"
const d = new TreeMultiDict<number, string>([
[1, 'Ein'],
[2, 'dos'],
[1, 'uno'],
[2, 'Zwei'],
[2, 'duo'],
])
const oneInDifferentLanguages = [...d.getValues(1)];
for (const word of oneInDifferentLanguages) {
console.log(`The number 1 can be translated as '${word}'`);
}
const [added, threeCursor] = d.emplace(3, 'tres')
if (d.hasKey(3)) {
console.log(`The dictionary now has 3 in its keys.`);
} else {
console.log(`The dictionary does not contain 3.`);
}
console.log(`The dictionary now has ${d.size} elements.`)
d.deleteAt(threeCursor)
The output of the above program:
The number 1 can be translated as as 'uno' The number 1 can be translated as as 'Ein' The dictionary now has 3 in its keys. The dictionary now has 6 elements.
The callback given to methods that implement the hashTag protocol.
Simple sugar for an array-based pair. Used by dictionaries to denote the actual value that is stored in the collection.
A transparent Cursor that only works on the right RB tree.
A symbol that is used to define a custom hash method for a certain class or object.
If this tag is present on an object, lessThan will use the method associated with this tag to compare the given object with something else.
Note that the value passed to the object's method does not have to be of the same type. It may be possible that a number is passed in, or something else entirely. It is your responsibility to perform the necessary checks.
class Character {
constructor(public readonly charCode) {
}
public [compareTag](other: any): boolean {
return other instanceof Character
&& this.charCode < other.charCode;
}
}
A symbol that is used to define a custom hash method for a certain class or object.
If this tag is present on an object, hash will call it with a callback that you can use to add your fields to the resulting hash.
import { hashTag, Hasher } from "scl";
class Person {
constructor(
public fullName: string,
public email: string,
) {
}
[hashTag](h: Hasher): void {
h(this.fullName);
}
}
A symbol that is used to define a custom equality operator for a class or object.
import { isEqual, isEqualTag } from "scl";
class Cat {
constructor(
public owner: Person,
public name: string,
public age: number
) {
}
public [isEqualTag](other: any) {
return value instanceof Cat
&& isEqual(cat.owner, other.owner)
&& cat.name === other.name;
}
}
Hash any value to a number that should provide the least amount of collisions.
This method will use hashTag if it is present on an object to hash according to a method you provided.
The logic of this hash function was roughly taken from this StackOverflow answer.
The value to hash
A hash code
Check whether two values are the same
If a
is an object that contains the isEqualTag, then this function
will call that method and return whatever that method returned. If b
contains the isEqualTag, it will attempt the same with b
. This way,
you can define your own classes with custom equality operators. See the
isEqualTag for more information.
Built-in JavaScript objects are just checked as if they were encoded to a JSON format and the resulting ouput is identical. For exmple, two plain JavaScript are the same if their enumerable keys contain the same values.
Check whether the given value is smaller than another value.
If a value is an object that contains a compareTag, then this function will call that method and return whatever that method returned. This way, you can define your own classes with custom comparison operators. See the compareTag for an example.
There are some specific rules when it comes to checking built-in JavaScript objects:
The above rules might seem strange at first, but they ensure that we can perform equality checks on string, arrays and objects by just using lessThan, as demonstrated in the following code:
import { lessThan } from "scl";
function equalByLesser(a, b) {
return !lessThan(a, b) && !lessThan(b, a);
}
console.log(equalByLesser(1, 1)) // true
console.log(equalByLesser(1, 2)) // false
console.log(equalByLesser('foo', 'foo')) // true
console.log(equalByLesser('foo', 'bar')) // false
console.log(equalByLesser([1, 2], [1, 2])) // true
console.log(equalByLesser([1, 2], [1, 2, 3])) // false
console.log(equalByLesser({ foo: 42 }, { foo: 42 }) // true
console.log(equalByLesser({ foo: 42 }, { foo: 42, bar: 33 }) // false
Generated using TypeDoc
A transparent Cursor that only works on the right AVL tree.