@thi.ng/associative
This project is part of the
@thi.ng/umbrella monorepo.
About
This package provides alternative Set
& Map
data type
implementations with customizable equality semantics, as well as common
operations working with these types:
- Array based
ArraySet
, Linked List based LLSet
,
Skiplist based SortedMap
& SortedSet
and customizable EquivMap
implement the full ES6
Map/Set APIs and additional features:
- range query iterators (via
entries()
, keys()
, values()
)
(sorted types only) ICopy
, IEmpty
& IEquiv
implementationsICompare
implementation for sorted types- multiple value additions / updates / deletions via
into()
,
dissoc()
(maps) and disj()
(sets) - configurable key equality & comparison (incl. default
implementations)
- getters w/ optional "not-found" default value
fromObject()
converters (for maps only)
- Polymorphic set operations (union, intersection, difference) - works
with both native and custom Sets and retains their types
- Natural & selective
joins
(incl. key renaming, ported from Clojure)
- Key-value pair inversion for maps and vanilla objects
- i.e. swaps
K => V
to V => K
- Single or multi-property index generation for maps and objects
- Key selection & renaming for maps and objects
Why?
The native ES6 implementations use object reference identity to
determine key containment, but often it's more practical and useful to
use equivalent value semantics for this purpose, especially when keys
are structured data (arrays / objects).
Note: It's the user's responsibility to ensure the inserted keys are
kept immutable (even if technically they're not).
Comparison with ES6 native types
a = [1, 2];
b = [1, 2];
Using native implementations
set = new Set();
set.add(a);
set.has(b);
map = new Map();
map.set(a, "foo");
map.get(b);
Using custom implementations:
import * as assoc from "@thi.ng/associative";
set = new assoc.ArraySet();
set.add(a);
set.add({a: 1});
set.has(b);
set.has({a: 1});
set = new assoc.LLSet();
set.add(a);
set.add({a: 1});
set.has(b);
set.has({a: 1});
map = new assoc.EquivMap();
map = new assoc.EquivMap(null, { keys: assoc.ArraySet });
map.set(a, "foo");
map.get(b);
set = new assoc.SortedSet([a, [-1, 2], [-1, -2]]);
set.has(b);
map = new assoc.SortedMap([[a, "foo"], [[-1,-2], "bar"]]);
map.get(b);
map.get([3,4], "n/a");
Installation
yarn add @thi.ng/associative
Dependencies
Types
IEquivSet
All Set
implementations in this package implement the
IEquivSet
interface, an extension of the native ES6 Set API.
ArraySet
Simple array based Set
implementation which by default uses
@thi.ng/equiv
for value equivalence checking.
LLSet
Similar to ArraySet
, but uses
@thi.ng/dcons linked list
as backing storage for values.
EquivMap
This Map
implementation uses a native ES6 Map
as backing storage for
its key-value pairs and an additional IEquivSet
implementation for
canonical keys. By default uses ArraySet
for this purpose.
SortedMap
Alternative implementation of the ES6 Map API using a Skip list as
backing store and support for configurable key equality and sorting
semantics. Like with sets, uses @thi.ng/equiv & @thi.ng/compare by
default.
William Pugh's (creator of this data structure) description:
"Skip lists are probabilistic data structures that have the same
asymptotic expected time bounds as balanced trees, are simpler, faster
and use less space."
Data structure description:
Ranged queries
map = new assoc.SortedMap([
["c", 3], ["a", 1], ["d", 4], ["b", 2]
]);
[...map.entries("c")]
[...map.entries("cc")]
[...map.entries(undefined, true)]
[...map.entries("c", true)]
SortedSet
Sorted set implementation with standard ES6 Set API, customizable value
equality and comparison semantics and additional functionality:
- range queries (via
entries
, keys
, values
) - multiple value addition/deletion via
into()
and disj()
Furthermore, this class implements the ICopy
, IEmpty
, ICompare
and
IEquiv
interfaces defined by @thi.ng/api
. The latter two allow
instances to be used as keys themselves in other data types defined in
this (and other) package(s).
This set uses a SortedMap
as backing store.
Usage examples
TODO... Please see
tests
and documentation in source code for now...
Authors
License
© 2017 - 2018 Karsten Schmidt // Apache Software License 2.0