enumset32

High-performance, typesafe, small ordered set implemented in TypeScript

Usage no npm install needed!

<script type="module">
  import enumset32 from 'https://cdn.skypack.dev/enumset32';
</script>

README

enumset32

enumset32 License: MPLv2 Follow this project on Twitter

High-performance, typesafe, small ordered set (up to 32 members) implemented in TypeScript

Please consider supporting The Typeverse Project (which includes enumset32) on Patreon.

enumset32 is specialized typesafe set implementation for use with TypeScript numeric enum types having a maximum of 32 members.

The members of the set are defined by a TypeScript numeric enum object. An enumset32 value is extremely compact compared to a JavaScript object as it's runtime representation is merely the lower 32 bits of a primitive JavaScript number value.

The time and space performance characteristics of enumset32 are uber-superb.

As an additional bonus, enumset32 is implementated in TypeScript. This makes for a high-quality, typesafe alternative to otherwise tedious coding and bit-fiddling with JavaScript numbers.

The Java standard library has a class called EnumSet and enumset32 as implemented by The Typeverse Project in TypeScript is very similar in concept.

To understand the "why" for enumset32, the documentation for the EnumSet class in Oracle's Java SE 12 & JDK 12 Docs is good background reading.

Note: Prior to the release of v1.0.0 and depending on your feedback the API is subject to change.

Quickstart Tutorial

Installation

$ npm install --save enumset32

As with most other npm packages enumset32 may also be installed with other package managers such as yarn and pnpm.

Creating enumsets

import { Enumset32, UniversalEnumset32 } from 'enumset32';

// Start out by declaring a TypeScript numeric enum for constructing a universal
// set comprising solely of only members of this enum. The enum members must be
// integer-valued numbers in the range 0..31 inclusive.

enum FileAttribute {
  FILE,
  DIRECTORY,
  SYMLINK,
  HIDDEN = 31
}

// Use the generic UniversalEnumset32 factory constructor function to create
// an enum universe specific to the type of the declared enum.

let fileAttributes: UniversalEnumset32<typeof FileAttribute> = UniversalEnumset32(FileAttribute);

// Creating (sub)sets from discrete enum members in this enum universe:

let fileFlag: Enumset32<typeof FileAttribute> = fileAttributes.set(FileAttribute.FILE);

// display result as string of digits in base2
console.log(fileAttributes.toDigitString(fileFlag, 2));
// => 1

// display result as an array of enum member keys
console.log(fileAttributes.enumKeys(fileFlag));
// => [ "FILE" ]

let fileOrDirectoryFlags: Enumset32<typeof FileAttribute> = fileAttributes.set(
  FileAttribute.FILE,
  FileAttribute.DIRECTORY
);

console.log(fileAttributes.toDigitString(fileOrDirectoryFlags, 2));
// => 11

console.log(fileAttributes.enumKeys(fileOrDirectoryFlags));
// => [ "FILE", "DIRECTORY" ]

let hiddenFlag: Enumset32<typeof FileAttribute> = fileAttributes.set(FileAttribute.HIDDEN);

console.log(fileAttributes.toDigitString(hiddenFlag, 2));
// => 10000000000000000000000000000000

console.log(fileAttributes.enumKeys(hiddenFlag));
// => [ "HIDDEN" ]

Operations on enumsets

// Union of an enumset with a discrete enum member

let hiddenFileOrDirectoryFlags: Enumset32<typeof FileAttribute> = fileAttributes.add(
  fileOrDirectoryFlags,
  FileAttribute.HIDDEN
);

console.log(fileAttributes.toDigitString(hiddenFileOrDirectoryFlags, 2));
// => 10000000000000000000000000000011

console.log(fileAttributes.enumKeys(hiddenFileOrDirectoryFlags));
// => [ "FILE", "DIRECTORY", "HIDDEN" ]

// Union of an enumset with another enumset

let fileOrDirectoryFlags2: Enumset32<typeof FileAttribute> = fileAttributes.addAll(
  fileOrDirectoryFlags,
  fileFlag
);

console.log(fileAttributes.equal(fileOrDirectoryFlags2, fileOrDirectoryFlags));
// => true

console.log(fileAttributes.enumKeys(fileOrDirectoryFlags2));
// => [ "FILE", "DIRECTORY" ]

// Intersection an enumset with another enumset

let testFlags: Enumset32<typeof FileAttribute> = fileAttributes.retainAll(
  fileOrDirectoryFlags,
  hiddenFlag
);

console.log(fileAttributes.empty(testFlags));
// => true

console.log(fileAttributes.enumKeys(testFlags));
// => []

Querying enumsets

// Test presence of a discrete enum member in an enumset

console.log(fileAttributes.includes(fileOrDirectoryFlags, FileAttribute.HIDDEN));
// => false since HIDDEN is absent from 1st enumset

// Test presence of every enum member of 2nd enumset in 1st enumset

console.log(fileAttributes.includesEvery(fileOrDirectoryFlags, hiddenFileOrDirectoryFlags));
// => false since HIDDEN is absent from 1st enumset

JavaScript and TypeScript Examples

The enumset32 package is designed to be used either with vanilla JavaScript (so no transpilation step is required) or with TypeScript for typesafety.

Please refer to the code in the examples directory for both JavaScript and TypeScript examples.

API

See here for the complete enumset32 API.

Benchmarks

See the charts comparing the relative performance of ES2015 Native Set, enumset32, fp-ts & Lodash with respect to common set operations.

License

Mozilla Public License Version 2.0 (MPL-2.0).

Copyright © 2019 Justin Johansson (https://github.com/indiescripter).