enumset32
Version:
High-performance, typesafe, small ordered set implemented in TypeScript
210 lines (140 loc) • 6.55 kB
Markdown
enumset32
=========
[](https://mozilla.org/MPL/2.0/)
[](https://twitter.com/typeverse)
> High-performance, typesafe, small ordered set (up to 32 members) implemented in TypeScript
Please consider supporting
[The Typeverse Project](https://www.patreon.com/indiescripter) (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](https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/EnumSet.html)
is good background reading.
**Note:** Prior to the release of v1.0.0 and depending on
[your feedback](https://github.com/Typeverse/enumset32/issues)
the API is subject to change.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Quickstart Tutorial](#quickstart-tutorial)
- [Installation](#installation)
- [Creating enumsets](#creating-enumsets)
- [Operations on enumsets](#operations-on-enumsets)
- [Querying enumsets](#querying-enumsets)
- [JavaScript and TypeScript Examples](#javascript-and-typescript-examples)
- [API](#api)
- [Benchmarks](#benchmarks)
- [License](#license)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Quickstart Tutorial
### Installation
```sh
$ 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
```ts
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" ]
```
```ts
// 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));
// => []
```
```ts
// 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
```
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](https://github.com/Typeverse/enumset32/tree/master/examples)
for both JavaScript and TypeScript examples.
## API
[See here](./doc/API.md) for the complete *enumset32* API.
## Benchmarks
[See the charts](./benchmarks/README.md) comparing the **relative** performance
of [ES2015 Native Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set),
enumset32, [fp-ts](https://github.com/gcanti/fp-ts) &
[Lodash](https://github.com/lodash/lodash)
with respect to common set operations.
## License
Mozilla Public License Version 2.0 ([MPL-2.0](./LICENSE)).
Copyright © 2019 Justin Johansson
([https://github.com/indiescripter](https://github.com/indiescripter)).