UNPKG

@thi.ng/associative

Version:

ES Map/Set-compatible implementations with customizable equality semantics & supporting operations

131 lines (130 loc) 3.35 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; import { SEMAPHORE } from "@thi.ng/api/api"; import { findIndex } from "@thi.ng/arrays/find"; import { equiv } from "@thi.ng/equiv"; import { dissoc } from "./dissoc.js"; import { __equivSet } from "./internal/equiv.js"; import { __inspectable } from "./internal/inspect.js"; import { into } from "./into.js"; const __private = /* @__PURE__ */ new WeakMap(); const __vals = (inst) => __private.get(inst).vals; let ArraySet = class extends Set { constructor(vals, opts = {}) { super(); __private.set(this, { equiv: opts.equiv || equiv, vals: [] }); vals && this.into(vals); } *[Symbol.iterator]() { yield* __vals(this); } get [Symbol.species]() { return ArraySet; } get [Symbol.toStringTag]() { return "ArraySet"; } get size() { return __vals(this).length; } copy() { const { equiv: equiv2, vals } = __private.get(this); const s = new ArraySet(null, { equiv: equiv2 }); __private.get(s).vals = vals.slice(); return s; } empty() { return new ArraySet(null, this.opts()); } clear() { __vals(this).length = 0; } first() { if (this.size) { return __vals(this)[0]; } } add(key) { !this.has(key) && __vals(this).push(key); return this; } into(keys) { return into(this, keys); } has(key) { return this.get(key, SEMAPHORE) !== SEMAPHORE; } /** * Returns the canonical value for `x`, if present. If the set * contains no equivalent for `x`, returns `notFound`. * * @param key - search key * @param notFound - default value */ get(key, notFound) { const { equiv: equiv2, vals } = __private.get(this); const i = findIndex(vals, key, equiv2); return i >= 0 ? vals[i] : notFound; } delete(key) { const { equiv: equiv2, vals } = __private.get(this); for (let i = vals.length; i-- > 0; ) { if (equiv2(vals[i], key)) { vals.splice(i, 1); return true; } } return false; } disj(keys) { return dissoc(this, keys); } equiv(o) { return __equivSet(this, o); } /** * The value args given to the callback `fn` MUST be treated as * readonly/immutable. This could be enforced via TS, but would * break ES6 Set interface contract. * * @param fn - * @param thisArg - */ forEach(fn, thisArg) { const vals = __vals(this); for (let i = vals.length; i-- > 0; ) { const v = vals[i]; fn.call(thisArg, v, v, this); } } *entries() { for (let v of __vals(this)) { yield [v, v]; } } *keys() { yield* __vals(this); } *values() { yield* __vals(this); } opts() { return { equiv: __private.get(this).equiv }; } }; ArraySet = __decorateClass([ __inspectable ], ArraySet); const defArraySet = (vals, opts) => new ArraySet(vals, opts); export { ArraySet, defArraySet };