@thi.ng/associative
Version:
ES Map/Set-compatible implementations with customizable equality semantics & supporting operations
131 lines (130 loc) • 3.35 kB
JavaScript
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
};