Curated collection of efficient data structures for JavaScript/TypeScript applications.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Memory-efficient resizable arrays with typed backing storage and bit-packed boolean arrays for space optimization.
Dynamic resizable array with typed backing storage and configurable growth policies.
/**
* Dynamic vector with typed array backing storage
* @param ArrayClass Constructor for the backing array type
* @param initialCapacityOrOptions Initial capacity or configuration options
*/
function Vector(
ArrayClass: ArrayConstructor,
initialCapacityOrOptions?: number | VectorOptions
): Vector;
interface VectorOptions {
/** Initial number of elements (default: 0) */
initialLength?: number;
/** Initial allocated capacity (default: computed from initialLength) */
initialCapacity?: number;
/** Custom growth policy function (default: 1.5x growth) */
policy?: (capacity: number) => number;
/** Whether to create a factory function (default: false) */
factory?: boolean;
}
interface Vector {
/** Current number of elements */
readonly length: number;
/** Current allocated capacity */
readonly capacity: number;
/** Alias for length */
readonly size: number;
/** Set value at index, returns this for chaining */
set(index: number, value: number): this;
/** Get value at index, returns undefined if out of bounds */
get(index: number): number | undefined;
/** Add value to end, returns new length */
push(value: number): number;
/** Remove and return last value */
pop(): number | undefined;
/** Change allocated capacity to exact size */
reallocate(capacity: number): this;
/** Grow capacity to at least the specified size */
grow(capacity?: number): this;
/** Change length, growing or shrinking as needed */
resize(length: number): this;
/** Apply growth policy, returns new capacity */
applyPolicy(override?: number): number;
/** Iterate over values */
values(): IterableIterator<number>;
/** Iterate over [index, value] pairs */
entries(): IterableIterator<[number, number]>;
/** Default iterator (same as values) */
[Symbol.iterator](): IterableIterator<number>;
/** Execute callback for each element */
forEach(callback: (value: number, index: number, vector: this) => void, scope?: any): void;
/** Debug representation */
inspect(): any;
}Usage Examples:
import {Vector} from "mnemonist";
// Create vector with Float32Array backing
const vector = new Vector(Float32Array, 10);
vector.push(1.5, 2.7, 3.14);
console.log(vector.get(0)); // 1.5
console.log(vector.length); // 3
// With custom growth policy
const customVector = new Vector(Int32Array, {
initialCapacity: 8,
policy: (capacity) => capacity * 2 // Double on growth
});
// Iteration
for (const value of vector) {
console.log(value);
}
vector.forEach((value, index) => {
console.log(`${index}: ${value}`);
});Factory methods for creating vectors from existing data.
/**
* Create vector from iterable data
*/
function from<T>(
iterable: Iterable<T>,
ArrayClass: ArrayConstructor,
capacity?: number
): Vector;Usage Examples:
import {Vector} from "mnemonist";
// From array
const vector = Vector.from([1, 2, 3], Float32Array);
// From other iterables
const fromSet = Vector.from(new Set([4, 5, 6]), Int32Array);
const fromMap = Vector.from(new Map().values(), Uint16Array);Pre-configured vector classes for each typed array type.
/**
* Pre-configured typed vector variants
*/
function Int8Vector(initialCapacityOrOptions?: number | VectorOptions): Int8Vector;
function Uint8Vector(initialCapacityOrOptions?: number | VectorOptions): Uint8Vector;
function Uint8ClampedVector(initialCapacityOrOptions?: number | VectorOptions): Uint8ClampedVector;
function Int16Vector(initialCapacityOrOptions?: number | VectorOptions): Int16Vector;
function Uint16Vector(initialCapacityOrOptions?: number | VectorOptions): Uint16Vector;
function Int32Vector(initialCapacityOrOptions?: number | VectorOptions): Int32Vector;
function Uint32Vector(initialCapacityOrOptions?: number | VectorOptions): Uint32Vector;
function Float32Vector(initialCapacityOrOptions?: number | VectorOptions): Float32Vector;
function Float64Vector(initialCapacityOrOptions?: number | VectorOptions): Float64Vector;
function PointerVector(initialCapacityOrOptions?: number | VectorOptions): PointerVector;Usage Examples:
import {
Int8Vector, Uint32Vector, Float32Vector, PointerVector
} from "mnemonist";
// Signed 8-bit integers (-128 to 127)
const bytes = new Int8Vector();
bytes.push(-50, 0, 127);
// Unsigned 32-bit integers (0 to 4,294,967,295)
const indices = new Uint32Vector();
indices.push(1000000, 2000000);
// 32-bit floats
const coordinates = new Float32Vector();
coordinates.push(1.5, -2.7, 3.14159);
// Automatically sized pointers (Uint16Array, Uint32Array, or Float64Array)
const pointers = new PointerVector();Typed Vector Static Methods:
// Each typed vector has its own from method
Int8Vector.from(iterable: Iterable<number>, capacity?: number): Int8Vector;
Uint32Vector.from(iterable: Iterable<number>, capacity?: number): Uint32Vector;
Float32Vector.from(iterable: Iterable<number>, capacity?: number): Float32Vector;
// ... same pattern for all typed variantsDynamic bit array storing boolean values efficiently with 32 bits per 32-bit word.
/**
* Dynamic bit vector with efficient boolean storage
* @param initialLengthOrOptions Initial length or configuration options
*/
function BitVector(initialLengthOrOptions?: number | BitVectorOptions): BitVector;
interface BitVectorOptions {
/** Initial number of bits (default: 0) */
initialLength?: number;
/** Initial allocated capacity in bits (default: computed from initialLength) */
initialCapacity?: number;
/** Custom growth policy function (default: 1.5x growth) */
policy?: (capacity: number) => number;
}
interface BitVector {
/** Current number of bits */
readonly length: number;
/** Current allocated capacity in bits (always multiple of 32) */
readonly capacity: number;
/** Number of bits set to 1 */
readonly size: number;
/** Set bit at index to value (1 or 0), returns this for chaining */
set(index: number, value?: boolean | number): this;
/** Set bit at index to 0, returns this for chaining */
reset(index: number): this;
/** Toggle bit at index, returns this for chaining */
flip(index: number): this;
/** Get bit value at index as number (0 or 1) */
get(index: number): number;
/** Get bit value at index as boolean */
test(index: number): boolean;
/** Add bit to end, returns new length */
push(value: boolean | number): number;
/** Remove and return last bit */
pop(): number | undefined;
/** Count of 1s from start to position i (exclusive) */
rank(i: number): number;
/** Position of rth 1-bit, or -1 if not found */
select(r: number): number;
/** Change allocated capacity */
reallocate(capacity: number): this;
/** Grow capacity to at least the specified size */
grow(capacity?: number): this;
/** Change length, growing or shrinking as needed */
resize(length: number): this;
/** Apply growth policy */
applyPolicy(override?: number): number;
/** Iterate over bit values (0 or 1) */
values(): IterableIterator<number>;
/** Iterate over [index, bit] pairs */
entries(): IterableIterator<[number, number]>;
/** Default iterator (same as values) */
[Symbol.iterator](): IterableIterator<number>;
/** Execute callback for each bit */
forEach(callback: (bit: number, index: number) => void, scope?: any): void;
/** Debug representation */
inspect(): any;
/** Return underlying Uint32Array as regular array */
toJSON(): Array<number>;
}Usage Examples:
import {BitVector} from "mnemonist";
// Create dynamic bit vector
const bits = new BitVector();
bits.push(true, false, true, true); // Add bits
console.log(bits.length); // 4
console.log(bits.size); // 3 (three 1-bits)
// Set individual bits
bits.set(10, 1); // Set bit 10 to 1
bits.reset(2); // Set bit 2 to 0
bits.flip(1); // Toggle bit 1
// Query bits
console.log(bits.test(10)); // true
console.log(bits.get(2)); // 0
// Rank and select operations
console.log(bits.rank(5)); // Count of 1s before position 5
console.log(bits.select(2)); // Position of 2nd 1-bit
// Iteration
for (const bit of bits) {
console.log(bit); // 0 or 1
}Fixed-size bit array optimized for known-size boolean collections.
/**
* Fixed-size bit set with efficient boolean storage
* @param length Fixed number of bits in the set
*/
function BitSet(length: number): BitSet;
interface BitSet {
/** Fixed number of bits in the set */
readonly length: number;
/** Number of bits currently set to 1 */
readonly size: number;
/** Set bit at index to value (1 or 0), returns this for chaining */
set(index: number, value?: boolean | number): void;
/** Set bit at index to specified value */
reset(index: number, value: boolean | number): void;
/** Toggle bit at index */
flip(index: number, value: boolean | number): void;
/** Get bit value at index as number (0 or 1) */
get(index: number): number;
/** Get bit value at index as boolean */
test(index: number): boolean;
/** Reset all bits to 0 and size to 0 */
clear(): void;
/** Count of 1s from start to position i (exclusive) */
rank(i: number): number;
/** Position of rth 1-bit, or -1 if not found */
select(r: number): number;
/** Iterate over bit values (0 or 1) */
values(): IterableIterator<number>;
/** Iterate over [index, bit] pairs */
entries(): IterableIterator<[number, number]>;
/** Default iterator (same as values) */
[Symbol.iterator](): IterableIterator<number>;
/** Execute callback for each bit */
forEach(callback: (bit: number, index: number) => void, scope?: any): void;
/** Debug representation */
inspect(): any;
/** Return underlying Uint32Array as regular array */
toJSON(): Array<number>;
}Usage Examples:
import {BitSet} from "mnemonist";
// Create fixed-size bit set
const flags = new BitSet(64); // 64 bits
flags.set(0, 1);
flags.set(63, 1);
console.log(flags.size); // 2
// Bulk operations
flags.clear(); // All bits to 0
console.log(flags.size); // 0
// Set multiple bits
[5, 10, 15, 20].forEach(i => flags.set(i, 1));
// Use as boolean array
const hasFeature = (feature: number) => flags.test(feature);
console.log(hasFeature(10)); // true
console.log(hasFeature(11)); // false
// Find positions of set bits
let position = -1;
let count = 0;
while ((position = flags.select(++count)) !== -1) {
console.log(`Bit ${position} is set`);
}/**
* Array constructor types supported by Vector
*/
type ArrayConstructor =
| Int8ArrayConstructor
| Uint8ArrayConstructor
| Uint8ClampedArrayConstructor
| Int16ArrayConstructor
| Uint16ArrayConstructor
| Int32ArrayConstructor
| Uint32ArrayConstructor
| Float32ArrayConstructor
| Float64ArrayConstructor;
/**
* Growth policy function type
* Takes current capacity, returns new capacity
*/
type GrowthPolicy = (capacity: number) => number;
/**
* Vector configuration options
*/
interface VectorOptions {
initialLength?: number;
initialCapacity?: number;
policy?: GrowthPolicy;
factory?: boolean;
}
/**
* BitVector configuration options
*/
interface BitVectorOptions {
initialLength?: number;
initialCapacity?: number;
policy?: GrowthPolicy;
}| Operation | Vector | BitVector | BitSet |
|---|---|---|---|
| Get/Set | O(1) | O(1) | O(1) |
| Push | O(1) amortized | O(1) amortized | N/A |
| Pop | O(1) | O(1) | N/A |
| Rank | N/A | O(n) | O(n) |
| Select | N/A | O(n) | O(n) |
| Memory per item | 1-8 bytes | 1/32 bytes | 1/32 bytes |
| Growth | Dynamic | Dynamic | Fixed |