@thi.ng/associative
Advanced tools
Comparing version 0.3.0 to 0.4.0
33
api.d.ts
@@ -1,14 +0,18 @@ | ||
import { Predicate2, Comparator } from "@thi.ng/api/api"; | ||
import { Comparator, ICopy, IEmpty, IEquiv, Predicate2 } from "@thi.ng/api/api"; | ||
export declare type Pair<K, V> = [K, V]; | ||
export declare const SEMAPHORE: unique symbol; | ||
export interface ArrayMapOpts<K> { | ||
equiv: Predicate2<K>; | ||
export interface IEquivSet<T> extends Set<T>, ICopy<IEquivSet<T>>, IEmpty<IEquivSet<T>>, IEquiv { | ||
readonly [Symbol.species]: EquivSetConstructor; | ||
into(xs: Iterable<T>): this; | ||
disj(xs: Iterable<T>): this; | ||
get(val: T, notFound?: any): any; | ||
first(): T; | ||
opts(): EquivSetOpts<T>; | ||
} | ||
export interface ArraySetOpts<T> { | ||
equiv: Predicate2<T>; | ||
export interface EquivSetConstructor { | ||
new (): IEquivSet<any>; | ||
new <T>(values?: Iterable<T>, opts?: EquivSetOpts<T>): IEquivSet<T>; | ||
readonly prototype: IEquivSet<any>; | ||
} | ||
/** | ||
* SortedMapOpts implementation config settings. | ||
*/ | ||
export interface SortedMapOpts<K> { | ||
export interface EquivSetOpts<T> { | ||
/** | ||
@@ -20,3 +24,11 @@ * Key equivalence predicate. MUST return truthy result if given | ||
*/ | ||
equiv: Predicate2<K>; | ||
equiv: Predicate2<T>; | ||
} | ||
export interface EquivMapOpts<K> extends EquivSetOpts<K> { | ||
keys: EquivSetConstructor; | ||
} | ||
/** | ||
* SortedMapOpts implementation config settings. | ||
*/ | ||
export interface SortedMapOpts<K> extends EquivSetOpts<K> { | ||
/** | ||
@@ -37,2 +49,3 @@ * Key comparison function. Must follow standard comparator contract | ||
* This value will be rounded up to next pow2. | ||
* | ||
* Default: 16 | ||
@@ -39,0 +52,0 @@ */ |
@@ -1,3 +0,2 @@ | ||
import { ICopy, IEmpty, IEquiv, Predicate2 } from "@thi.ng/api/api"; | ||
import { ArraySetOpts, Pair } from "./api"; | ||
import { EquivSetOpts, IEquivSet, Pair } from "./api"; | ||
/** | ||
@@ -12,4 +11,4 @@ * An alternative set implementation to the native ES6 Set type. Uses | ||
*/ | ||
export declare class ArraySet<T> extends Set<T> implements Iterable<T>, ICopy<ArraySet<T>>, IEmpty<ArraySet<T>>, IEquiv { | ||
constructor(vals?: Iterable<T>, eq?: Predicate2<T>); | ||
export declare class ArraySet<T> extends Set<T> implements IEquivSet<T> { | ||
constructor(vals?: Iterable<T>, opts?: Partial<EquivSetOpts<T>>); | ||
[Symbol.iterator](): IterableIterator<any>; | ||
@@ -34,3 +33,3 @@ readonly [Symbol.species]: typeof ArraySet; | ||
delete(x: T): boolean; | ||
disj(...xs: T[]): this; | ||
disj(xs: Iterable<T>): this; | ||
equiv(o: any): boolean; | ||
@@ -41,3 +40,3 @@ forEach(fn: (val: T, val2: T, set: Set<T>) => void, thisArg?: any): void; | ||
values(): IterableIterator<any>; | ||
getOpts(): ArraySetOpts<T>; | ||
opts(): EquivSetOpts<T>; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const equiv_1 = require("@thi.ng/api/equiv"); | ||
const dcons_1 = require("@thi.ng/dcons"); | ||
const api_1 = require("./api"); | ||
@@ -17,5 +16,5 @@ const __private = new WeakMap(); | ||
class ArraySet extends Set { | ||
constructor(vals, eq = equiv_1.equiv) { | ||
constructor(vals, opts = {}) { | ||
super(); | ||
__private.set(this, { equiv: eq, vals: new dcons_1.DCons() }); | ||
__private.set(this, { equiv: opts.equiv || equiv_1.equiv, vals: [] }); | ||
vals && this.into(vals); | ||
@@ -33,16 +32,15 @@ } | ||
copy() { | ||
const $this = __private.get(this); | ||
const s = new ArraySet(null, $this.equiv); | ||
__private.get(s).vals = $this.vals.copy(); | ||
const s = new ArraySet(null, this.opts()); | ||
__private.get(s).vals = [...__private.get(this).vals]; | ||
return s; | ||
} | ||
empty() { | ||
return new ArraySet(null, __private.get(this).equiv); | ||
return new ArraySet(null, this.opts()); | ||
} | ||
clear() { | ||
__private.get(this).vals.clear(); | ||
__private.get(this).vals.length = 0; | ||
} | ||
first() { | ||
if (this.size) { | ||
return __private.get(this).vals.head.value; | ||
return __private.get(this).vals[0]; | ||
} | ||
@@ -73,8 +71,7 @@ } | ||
const eq = $this.equiv; | ||
let i = $this.vals.head; | ||
while (i) { | ||
if (eq(i.value, x)) { | ||
return i.value; | ||
const vals = $this.vals; | ||
for (let i = vals.length - 1; i >= 0; i--) { | ||
if (eq(vals[i], x)) { | ||
return vals[i]; | ||
} | ||
i = i.next; | ||
} | ||
@@ -86,13 +83,12 @@ return notFound; | ||
const eq = $this.equiv; | ||
let i = $this.vals.head; | ||
while (i) { | ||
if (eq(i.value, x)) { | ||
$this.vals.splice(i, 1); | ||
const vals = $this.vals; | ||
for (let i = vals.length - 1; i >= 0; i--) { | ||
if (eq(vals[i], x)) { | ||
vals.splice(i, 1); | ||
return true; | ||
} | ||
i = i.next; | ||
} | ||
return false; | ||
} | ||
disj(...xs) { | ||
disj(xs) { | ||
for (let x of xs) { | ||
@@ -113,8 +109,7 @@ this.delete(x); | ||
} | ||
let i = __private.get(this).vals.head; | ||
while (i) { | ||
if (!o.has(i.value)) { | ||
const vals = __private.get(this).vals; | ||
for (let i = vals.length - 1; i >= 0; i--) { | ||
if (!o.has(vals[i])) { | ||
return false; | ||
} | ||
i = i.next; | ||
} | ||
@@ -124,6 +119,6 @@ return true; | ||
forEach(fn, thisArg) { | ||
let i = __private.get(this).vals.head; | ||
while (i) { | ||
fn.call(thisArg, i.value, i.value, this); | ||
i = i.next; | ||
const vals = __private.get(this).vals; | ||
for (let i = vals.length - 1; i >= 0; i--) { | ||
const v = vals[i]; | ||
fn.call(thisArg, v, v, this); | ||
} | ||
@@ -142,3 +137,3 @@ } | ||
} | ||
getOpts() { | ||
opts() { | ||
return { equiv: __private.get(this).equiv }; | ||
@@ -145,0 +140,0 @@ } |
@@ -6,2 +6,18 @@ # Change Log | ||
<a name="0.4.0"></a> | ||
# [0.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.3.0...@thi.ng/associative@0.4.0) (2018-04-13) | ||
### Features | ||
* **associative:** add renameKeysMap ([bfabe80](https://github.com/thi-ng/umbrella/commit/bfabe80)) | ||
### Performance Improvements | ||
* **associative:** update equiv() impls ([d1178ac](https://github.com/thi-ng/umbrella/commit/d1178ac)) | ||
<a name="0.3.0"></a> | ||
@@ -8,0 +24,0 @@ # [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.2.0...@thi.ng/associative@0.3.0) (2018-04-13) |
@@ -1,3 +0,4 @@ | ||
export * from "./array-map"; | ||
export * from "./array-set"; | ||
export * from "./equiv-map"; | ||
export * from "./ll-set"; | ||
export * from "./sorted-map"; | ||
@@ -4,0 +5,0 @@ export * from "./sorted-set"; |
@@ -6,4 +6,5 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./array-map")); | ||
__export(require("./array-set")); | ||
__export(require("./equiv-map")); | ||
__export(require("./ll-set")); | ||
__export(require("./sorted-map")); | ||
@@ -10,0 +11,0 @@ __export(require("./sorted-set")); |
@@ -1,7 +0,20 @@ | ||
import { ArrayMap } from "./array-map"; | ||
import { EquivMap } from "./equiv-map"; | ||
/** | ||
* Takes a set of objects and array of indexing keys. Calls | ||
* `selectKeysObj` on each set value and used returned objects as new | ||
* keys to group original values. Returns a map of sets. | ||
* | ||
* @param records | ||
* ``` | ||
* indexed( | ||
* new Set([{a: 1, b: 1}, {a: 1, b: 2}, {a: 1, b: 1, c: 2}]), | ||
* ["a","b"] | ||
* ) | ||
* // EquivMap { | ||
* // { a: 1, b: 1 } => Set { { a: 1, b: 1 }, { a: 1, b: 1, c: 2 } }, | ||
* // { a: 1, b: 2 } => Set { { a: 1, b: 2 } } } | ||
* ``` | ||
* | ||
* @param records set of objects to index | ||
* @param ks keys used for indexing | ||
*/ | ||
export declare function indexed(records: Set<any>, ks: PropertyKey[]): ArrayMap<any, Set<any>>; | ||
export declare function indexed<T>(records: Set<T>, ks: PropertyKey[]): EquivMap<any, Set<T>>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const array_map_1 = require("./array-map"); | ||
const equiv_map_1 = require("./equiv-map"); | ||
const select_keys_1 = require("./select-keys"); | ||
const utils_1 = require("./utils"); | ||
/** | ||
* Takes a set of objects and array of indexing keys. Calls | ||
* `selectKeysObj` on each set value and used returned objects as new | ||
* keys to group original values. Returns a map of sets. | ||
* | ||
* @param records | ||
* ``` | ||
* indexed( | ||
* new Set([{a: 1, b: 1}, {a: 1, b: 2}, {a: 1, b: 1, c: 2}]), | ||
* ["a","b"] | ||
* ) | ||
* // EquivMap { | ||
* // { a: 1, b: 1 } => Set { { a: 1, b: 1 }, { a: 1, b: 1, c: 2 } }, | ||
* // { a: 1, b: 2 } => Set { { a: 1, b: 2 } } } | ||
* ``` | ||
* | ||
* @param records set of objects to index | ||
* @param ks keys used for indexing | ||
*/ | ||
function indexed(records, ks) { | ||
const res = new array_map_1.ArrayMap(); | ||
const res = new equiv_map_1.EquivMap(); | ||
let m, ik, rv; | ||
@@ -17,3 +31,3 @@ for (m of records) { | ||
if (!rv) { | ||
res.set(ik, rv = new Set()); | ||
res.set(ik, rv = utils_1.empty(records, Set)); | ||
} | ||
@@ -20,0 +34,0 @@ rv.add(m); |
import { IObjectOf } from "@thi.ng/api/api"; | ||
/** | ||
* Returns a new map in which the original values are used as keys and | ||
* original keys as values. | ||
* | ||
* ``` | ||
* invertMap(new Map([["a", 1], ["b", 2]])); | ||
* // Map { 1 => 'a', 2 => 'b' } | ||
* ``` | ||
* | ||
* @param src | ||
*/ | ||
export declare function invertMap<K, V>(src: Map<K, V>): Map<V, K>; | ||
/** | ||
* Returns a new object in which the original values are used as keys | ||
* and original keys as values. | ||
* | ||
* ``` | ||
* invertObj({a: 1, b: 2}) | ||
* // { '1': 'a', '2': 'b' } | ||
* ``` | ||
* | ||
* @param src | ||
*/ | ||
export declare function invertObj(src: IObjectOf<PropertyKey>): IObjectOf<PropertyKey>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("./utils"); | ||
/** | ||
* Returns a new map in which the original values are used as keys and | ||
* original keys as values. | ||
* | ||
* ``` | ||
* invertMap(new Map([["a", 1], ["b", 2]])); | ||
* // Map { 1 => 'a', 2 => 'b' } | ||
* ``` | ||
* | ||
* @param src | ||
*/ | ||
function invertMap(src) { | ||
@@ -12,2 +23,13 @@ const dest = utils_1.empty(src, Map); | ||
exports.invertMap = invertMap; | ||
/** | ||
* Returns a new object in which the original values are used as keys | ||
* and original keys as values. | ||
* | ||
* ``` | ||
* invertObj({a: 1, b: 2}) | ||
* // { '1': 'a', '2': 'b' } | ||
* ``` | ||
* | ||
* @param src | ||
*/ | ||
function invertObj(src) { | ||
@@ -14,0 +36,0 @@ const dest = {}; |
import { IObjectOf } from "@thi.ng/api/api"; | ||
/** | ||
* Computes the natural join between the two sets of relations. Each set | ||
* is assumed to have plain objects as values with at least one of the | ||
* keys present in both sides. Furthermore the objects in each set are | ||
* assumed to have the same internal structure (i.e. sets of keys). | ||
* | ||
* ``` | ||
* join( | ||
* new Set([ | ||
* {id: 1, name: "foo"}, | ||
* {id: 2, name: "bar"}, | ||
* {id: 3, name: "baz"}]), | ||
* new Set([ | ||
* {id: 1, color: "red"}, | ||
* {id: 2, color: "blue"}]) | ||
* ) | ||
* // Set { | ||
* // { id: 1, color: 'red', name: 'foo' }, | ||
* // { id: 2, color: 'blue', name: 'bar' } | ||
* // } | ||
* ``` | ||
* | ||
* @param xrel | ||
* @param yrel | ||
*/ | ||
export declare function join<A, B>(xrel: Set<A>, yrel: Set<B>): any; | ||
export declare function joinWith<A, B>(xrel: Set<A>, yrel: Set<B>, km: IObjectOf<PropertyKey>): any; | ||
/** | ||
* Similar to `join()`, computes the join between two sets of relations, | ||
* using the given keys in `kmap` only. `kmap` can also be used to | ||
* rename join keys in `yrel` where needed, e.g. | ||
* | ||
* ``` | ||
* joinWith( | ||
* new Set([ | ||
* {id: 1, name: "foo"}, | ||
* {id: 2, name: "bar"}, | ||
* {id: 3, name: "baz"}]), | ||
* new Set([ | ||
* {type: 1, color: "red"}, | ||
* {type: 2, color: "blue"}]), | ||
* {id: "type"} | ||
* ) | ||
* ``` | ||
* If no renaming is desired, the values in `kmap` should be the same as | ||
* their respective keys. | ||
* | ||
* @param xrel | ||
* @param yrel | ||
* @param kmap keys to compute join for | ||
*/ | ||
export declare function joinWith<A, B>(xrel: Set<A>, yrel: Set<B>, kmap: IObjectOf<PropertyKey>): any; |
60
join.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const array_set_1 = require("./array-set"); | ||
const intersection_1 = require("./intersection"); | ||
@@ -11,2 +10,27 @@ const indexed_1 = require("./indexed"); | ||
const utils_1 = require("./utils"); | ||
/** | ||
* Computes the natural join between the two sets of relations. Each set | ||
* is assumed to have plain objects as values with at least one of the | ||
* keys present in both sides. Furthermore the objects in each set are | ||
* assumed to have the same internal structure (i.e. sets of keys). | ||
* | ||
* ``` | ||
* join( | ||
* new Set([ | ||
* {id: 1, name: "foo"}, | ||
* {id: 2, name: "bar"}, | ||
* {id: 3, name: "baz"}]), | ||
* new Set([ | ||
* {id: 1, color: "red"}, | ||
* {id: 2, color: "blue"}]) | ||
* ) | ||
* // Set { | ||
* // { id: 1, color: 'red', name: 'foo' }, | ||
* // { id: 2, color: 'blue', name: 'bar' } | ||
* // } | ||
* ``` | ||
* | ||
* @param xrel | ||
* @param yrel | ||
*/ | ||
function join(xrel, yrel) { | ||
@@ -26,3 +50,3 @@ if (xrel.size && yrel.size) { | ||
const idx = indexed_1.indexed(r, ks); | ||
const res = new array_set_1.ArraySet(); | ||
const res = utils_1.empty(xrel, Set); | ||
for (let x of s) { | ||
@@ -41,3 +65,27 @@ const found = idx.get(select_keys_1.selectKeysObj(x, ks)); | ||
exports.join = join; | ||
function joinWith(xrel, yrel, km) { | ||
/** | ||
* Similar to `join()`, computes the join between two sets of relations, | ||
* using the given keys in `kmap` only. `kmap` can also be used to | ||
* rename join keys in `yrel` where needed, e.g. | ||
* | ||
* ``` | ||
* joinWith( | ||
* new Set([ | ||
* {id: 1, name: "foo"}, | ||
* {id: 2, name: "bar"}, | ||
* {id: 3, name: "baz"}]), | ||
* new Set([ | ||
* {type: 1, color: "red"}, | ||
* {type: 2, color: "blue"}]), | ||
* {id: "type"} | ||
* ) | ||
* ``` | ||
* If no renaming is desired, the values in `kmap` should be the same as | ||
* their respective keys. | ||
* | ||
* @param xrel | ||
* @param yrel | ||
* @param kmap keys to compute join for | ||
*/ | ||
function joinWith(xrel, yrel, kmap) { | ||
if (xrel.size && yrel.size) { | ||
@@ -49,3 +97,3 @@ let r, s; | ||
s = yrel; | ||
k = invert_1.invertObj(km); | ||
k = invert_1.invertObj(kmap); | ||
} | ||
@@ -55,7 +103,7 @@ else { | ||
s = xrel; | ||
k = km; | ||
k = kmap; | ||
} | ||
const idx = indexed_1.indexed(r, utils_1.objValues(k)); | ||
const ks = Object.keys(k); | ||
const res = new array_set_1.ArraySet(); | ||
const res = utils_1.empty(xrel, Set); | ||
for (let x of s) { | ||
@@ -62,0 +110,0 @@ const found = idx.get(rename_keys_1.renameKeysObj(select_keys_1.selectKeysObj(x, ks), k)); |
@@ -0,2 +1,16 @@ | ||
/** | ||
* Merges all given maps in left-to-right order into `m`. | ||
* Returns `m`. | ||
* | ||
* @param m | ||
* @param maps | ||
*/ | ||
export declare function mergeMaps<K, V>(m: Map<K, V>, ...maps: Map<K, V>[]): Map<K, V>; | ||
/** | ||
* Merges all given objects in left-to-right order into `m`. | ||
* Returns `m`. | ||
* | ||
* @param m | ||
* @param maps | ||
*/ | ||
export declare function mergeObj(m: any, ...maps: any[]): any; |
14
merge.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Merges all given maps in left-to-right order into `m`. | ||
* Returns `m`. | ||
* | ||
* @param m | ||
* @param maps | ||
*/ | ||
function mergeMaps(m, ...maps) { | ||
@@ -12,2 +19,9 @@ for (let mm of maps) { | ||
exports.mergeMaps = mergeMaps; | ||
/** | ||
* Merges all given objects in left-to-right order into `m`. | ||
* Returns `m`. | ||
* | ||
* @param m | ||
* @param maps | ||
*/ | ||
function mergeObj(m, ...maps) { | ||
@@ -14,0 +28,0 @@ return Object.assign(m, ...maps); |
{ | ||
"name": "@thi.ng/associative", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations", | ||
@@ -12,3 +12,3 @@ "main": "./index.js", | ||
"build": "yarn run clean && tsc --declaration", | ||
"clean": "rm -rf *.js *.d.ts build doc", | ||
"clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", | ||
"cover": "yarn test && nyc report --reporter=lcov", | ||
@@ -15,0 +15,0 @@ "doc": "node_modules/.bin/typedoc --mode modules --out doc src", |
@@ -7,10 +7,10 @@ # @thi.ng/associative | ||
This package provided alternative Set & Map data type implementations | ||
with customizable equality semantics, as well as common operations | ||
working with these types: | ||
This package provides alternative `Set` & `Map` data type | ||
implementations with customizable equality semantics, as well as common | ||
operations working with these types: | ||
- Array based `ArrayMap` & `ArraySet` and | ||
- Array based `ArraySet`, Linked List based `LLSet`, | ||
[Skiplist](https://en.wikipedia.org/wiki/Skip_list) based `SortedMap` | ||
& `SortedSet` implement the full ES6 Map/Set APIs and additional | ||
features | ||
& `SortedSet` and customizable `EquivMap` implement the full ES6 | ||
Map/Set APIs and additional features: | ||
- range query iterators (via `entries()`, `keys()`, `values()`) | ||
@@ -20,5 +20,8 @@ (sorted types only) | ||
- `ICompare` implementation for sorted types | ||
- multiple value addition/deletion via `into()` and `disj()` | ||
- configurable key equality & comparison | ||
- 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 | ||
@@ -47,7 +50,10 @@ with both native and custom Sets and retains their types | ||
```ts | ||
// two objects w/ equal values | ||
// first two objects w/ equal values | ||
a = [1, 2]; | ||
b = [1, 2]; | ||
``` | ||
// using native implementations | ||
Using native implementations | ||
```ts | ||
set = new Set(); | ||
@@ -78,5 +84,18 @@ set.add(a); | ||
map = new assoc.ArrayMap(); | ||
set = new assoc.LLSet(); | ||
set.add(a); | ||
set.add({a: 1}); | ||
// LLSet { [ 1, 2 ], { a: 1 } } | ||
set.has(b); | ||
// true | ||
set.has({a: 1}); | ||
// true | ||
// by default EquivMap uses ArraySet for its canonical keys | ||
map = new assoc.EquivMap(); | ||
// with custom implementation | ||
map = new assoc.EquivMap(null, { keys: assoc.ArraySet }); | ||
map.set(a, "foo"); | ||
ArrayMap { [ 1, 2 ] => 'foo' } | ||
// EquivMap { [ 1, 2 ] => 'foo' } | ||
map.get(b); | ||
@@ -108,27 +127,36 @@ // "foo" | ||
### ArrayMap | ||
### IEquivSet | ||
This `Map` implementation uses a native ES6 `Map` as backing storage for | ||
key-value pairs and additional `ArraySet` for canonical keys. By default | ||
it too uses | ||
[@thi.ng/api/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/api/src/equiv.ts) | ||
for equivalence checking of keys. | ||
All `Set` implementations in this package implement the | ||
[IEquivSet](https://github.com/thi-ng/umbrella/tree/master/packages/associative/src/api.ts#L7) | ||
interface, an extension of the native ES6 Set API. | ||
### ArraySet | ||
This `Set` implementation uses | ||
[@thi.ng/dcons](https://github.com/thi-ng/umbrella/tree/master/packages/dcons) | ||
as backing storage for values and by default uses | ||
Simple array based `Set` implementation which by default uses | ||
[@thi.ng/api/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/api/src/equiv.ts) | ||
for equivalence checking. | ||
for value equivalence checking. | ||
### LLSet | ||
Similar to `ArraySet`, but uses | ||
[@thi.ng/dcons](https://github.com/thi-ng/umbrella/tree/master/packages/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 | ||
This class is an alternative implementation of the ES6 Map API using a | ||
Skip list as backing store and supports configurable key equality and | ||
sorting semantics. | ||
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/api/equiv & @thi.ng/api/compare | ||
by default. | ||
William Pugh (creator of this data structure) description: | ||
William Pugh's (creator of this data structure) description: | ||
> "Skip lists are a probabilistic data structures that have the same | ||
> "Skip lists are probabilistic data structures that have the same | ||
asymptotic expected time bounds as balanced trees, are simpler, faster | ||
@@ -151,3 +179,4 @@ and use less space." | ||
// forward w/ given start key | ||
// forward selection w/ given start key | ||
// also works with `keys()` and `values()` | ||
[...map.entries("c")] | ||
@@ -160,3 +189,7 @@ // [ [ 'c', 3 ], [ 'd', 4 ] ] | ||
// reverse | ||
// reverse order | ||
[...map.entries(undefined, true)] | ||
// [ [ 'd', 4 ], [ 'c', 3 ], [ 'b', 2 ], [ 'a', 1 ] ] | ||
// reverse order from start key | ||
[...map.entries("c", true)] | ||
@@ -163,0 +196,0 @@ // [ [ 'c', 3 ], [ 'b', 2 ], [ 'a', 1 ] ] |
import { IObjectOf } from "@thi.ng/api/api"; | ||
export declare function renameKeysMap<T>(src: Map<any, T>, km: IObjectOf<T>): Map<any, T>; | ||
export declare function renameKeysObj(src: any, km: IObjectOf<PropertyKey>): {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("./utils"); | ||
function renameKeysMap(src, km) { | ||
const dest = utils_1.empty(src, Map); | ||
for (let p of src) { | ||
const k = p[0]; | ||
const kk = km[k]; | ||
dest.set(kk !== undefined ? kk : k, p[1]); | ||
} | ||
return dest; | ||
} | ||
exports.renameKeysMap = renameKeysMap; | ||
function renameKeysObj(src, km) { | ||
@@ -7,3 +18,3 @@ const dest = {}; | ||
const kk = km[k]; | ||
dest[kk !== undefined ? kk : k] = src[k]; | ||
dest[kk != null ? kk : k] = src[k]; | ||
} | ||
@@ -10,0 +21,0 @@ return dest; |
import { IObjectOf } from "@thi.ng/api/api"; | ||
/** | ||
* Returns a new map of same type as input only containing given keys | ||
* (and only if they existed in the original map). | ||
* | ||
* @param src | ||
* @param ks selected keys | ||
*/ | ||
export declare function selectKeysMap<K, V>(src: Map<K, V>, ks: Iterable<K>): any; | ||
/** | ||
* Returns a new object only containing given keys (and only if they | ||
* existed in the original). | ||
* | ||
* @param src | ||
* @param ks | ||
*/ | ||
export declare function selectKeysObj<T>(src: IObjectOf<T>, ks: Iterable<PropertyKey>): any; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("./utils"); | ||
/** | ||
* Returns a new map of same type as input only containing given keys | ||
* (and only if they existed in the original map). | ||
* | ||
* @param src | ||
* @param ks selected keys | ||
*/ | ||
function selectKeysMap(src, ks) { | ||
@@ -14,2 +21,9 @@ const dest = utils_1.empty(src, Map); | ||
exports.selectKeysMap = selectKeysMap; | ||
/** | ||
* Returns a new object only containing given keys (and only if they | ||
* existed in the original). | ||
* | ||
* @param src | ||
* @param ks | ||
*/ | ||
function selectKeysObj(src, ks) { | ||
@@ -16,0 +30,0 @@ const dest = {}; |
@@ -10,3 +10,3 @@ import { IObjectOf, ICompare, ICopy, IEmpty, IEquiv } from "@thi.ng/api/api"; | ||
* | ||
* "Skip lists are a probabilistic data structures that have the same | ||
* "Skip lists are probabilistic data structures that have the same | ||
* asymptotic expected time bounds as balanced trees, are simpler, | ||
@@ -54,3 +54,3 @@ * faster and use less space." | ||
protected init(values: Iterable<Pair<K, V>>, opts: Partial<SortedMapOpts<K>>): Iterable<[K, V]>; | ||
getOpts(growFactor?: number): SortedMapOpts<K>; | ||
opts(growFactor?: number): SortedMapOpts<K>; | ||
/** | ||
@@ -57,0 +57,0 @@ * Recreates map with double capacity. |
@@ -29,3 +29,3 @@ "use strict"; | ||
* | ||
* "Skip lists are a probabilistic data structures that have the same | ||
* "Skip lists are probabilistic data structures that have the same | ||
* asymptotic expected time bounds as balanced trees, are simpler, | ||
@@ -73,9 +73,9 @@ * faster and use less space." | ||
clear() { | ||
this.init(null, Object.assign({}, this.getOpts(), { capacity: SortedMap.DEFAULT_CAP })); | ||
this.init(null, Object.assign({}, this.opts(), { capacity: SortedMap.DEFAULT_CAP })); | ||
} | ||
empty() { | ||
return new SortedMap(null, Object.assign({}, this.getOpts(), { capacity: SortedMap.DEFAULT_CAP })); | ||
return new SortedMap(null, Object.assign({}, this.opts(), { capacity: SortedMap.DEFAULT_CAP })); | ||
} | ||
copy() { | ||
return new SortedMap(this, this.getOpts()); | ||
return new SortedMap(this, this.opts()); | ||
} | ||
@@ -112,4 +112,4 @@ compare(o) { | ||
} | ||
for (let x of this) { | ||
if (!equiv_1.equiv(x[1], o.get(x[0]))) { | ||
for (let p of this.entries()) { | ||
if (!equiv_1.equiv(o.get(p[0]), p[1])) { | ||
return false; | ||
@@ -261,3 +261,3 @@ } | ||
} | ||
getOpts(growFactor = 1) { | ||
opts(growFactor = 1) { | ||
const $this = __private.get(this); | ||
@@ -275,3 +275,3 @@ return { | ||
grow() { | ||
const tmp = new SortedMap(this.entries(), this.getOpts(2)); | ||
const tmp = new SortedMap(this.entries(), this.opts(2)); | ||
__private.set(this, __private.get(tmp)); | ||
@@ -278,0 +278,0 @@ __private.delete(tmp); |
@@ -1,3 +0,3 @@ | ||
import { ICopy, IEmpty, IEquiv, ICompare } from "@thi.ng/api/api"; | ||
import { Pair, SortedSetOpts } from "./api"; | ||
import { ICompare } from "@thi.ng/api/api"; | ||
import { Pair, SortedSetOpts, IEquivSet } from "./api"; | ||
/** | ||
@@ -18,3 +18,3 @@ * Sorted set implementation with standard ES6 Set API, customizable | ||
*/ | ||
export declare class SortedSet<T> extends Set<T> implements ICopy<SortedSet<T>>, ICompare<Set<T>>, IEmpty<SortedSet<T>>, IEquiv { | ||
export declare class SortedSet<T> extends Set<T> implements IEquivSet<T>, ICompare<Set<T>> { | ||
/** | ||
@@ -40,9 +40,11 @@ * Creates new instance with optional given values and/or | ||
add(value: T): this; | ||
into(xs: Iterable<T>): this; | ||
clear(): void; | ||
first(): any; | ||
delete(value: T): boolean; | ||
disj(xs: Iterable<T>): this; | ||
forEach(fn: (val: T, val2: T, set: Set<T>) => void, thisArg?: any): void; | ||
has(value: T): boolean; | ||
get(value: T, notFound?: any): any; | ||
getOpts(): SortedSetOpts<T>; | ||
opts(): SortedSetOpts<T>; | ||
} |
@@ -45,6 +45,6 @@ "use strict"; | ||
copy() { | ||
return new SortedSet(this.keys(), this.getOpts()); | ||
return new SortedSet(this.keys(), this.opts()); | ||
} | ||
empty() { | ||
return new SortedSet(null, Object.assign({}, this.getOpts(), { capacity: sorted_map_1.SortedMap.DEFAULT_CAP })); | ||
return new SortedSet(null, Object.assign({}, this.opts(), { capacity: sorted_map_1.SortedMap.DEFAULT_CAP })); | ||
} | ||
@@ -78,4 +78,4 @@ compare(o) { | ||
} | ||
for (let x of this) { | ||
if (!o.has(x)) { | ||
for (let k of this.keys()) { | ||
if (!o.has(k)) { | ||
return false; | ||
@@ -99,2 +99,8 @@ } | ||
} | ||
into(xs) { | ||
for (let x of xs) { | ||
this.add(x); | ||
} | ||
return this; | ||
} | ||
clear() { | ||
@@ -110,2 +116,8 @@ __private.get(this).clear(); | ||
} | ||
disj(xs) { | ||
for (let x of xs) { | ||
this.delete(x); | ||
} | ||
return this; | ||
} | ||
forEach(fn, thisArg) { | ||
@@ -122,6 +134,6 @@ for (let p of this) { | ||
} | ||
getOpts() { | ||
return __private.get(this).getOpts(); | ||
opts() { | ||
return __private.get(this).opts(); | ||
} | ||
} | ||
exports.SortedSet = SortedSet; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
38
1694
220
0
69810