extra-map
Version:
A group of functions for working with Maps.
671 lines (667 loc) • 15.8 kB
JavaScript
function IDENTITY(v) {
return v;
}
function COMPARE(a, b) {
return a < b ? -1 : (a > b ? 1 : 0);
}
function fromRange(v, V, dv = 1) {
var n = (V - v) / dv, a = [];
for (var i = 0; i < n; ++i, v += dv)
a.push(v);
return a;
}
function index(x, i) {
var X = x.length;
return i >= 0 ? Math.min(i, X) : Math.max(X + i, 0);
}
function get$1(x, i) {
return x[index(x, i)];
}
function getAll$1(x, is) {
return is.map(i => get$1(x, i));
}
function last(x, vd) {
return x.length > 0 ? x[x.length - 1] : vd;
}
function subsequences(x, n = -1) {
return [...isubsequences(x, n)];
}
function* isubsequences(x, n = -1) {
var X = x.length;
if (n > X)
return;
if (n === X) {
yield x;
return;
}
if (n === 0 || X === 0) {
yield [];
return;
}
var y = x.slice(0, -1);
yield* isubsequences(y, n);
for (var s of isubsequences(y, n - 1)) {
s.push(x[X - 1]);
yield s;
}
}
function randomValue(x, fr = Math.random) {
var i = Math.floor(fr() * x.length);
return x[i];
}
function randomSubsequence(x, n = -1, fr = Math.random) {
var X = x.length;
if (n > X)
return null;
if (n >= 0)
return randomSubsequenceFixed(x, n, fr);
else
return randomSubsequenceAll(x, fr);
}
function randomSubsequenceFixed(x, n, fr) {
var is = fromRange(0, x.length);
randomPermutation$(is, n, fr).sort();
return getAll$1(x, is);
}
function randomSubsequenceAll(x, fr) {
var a = [];
for (var v of x)
if (fr() < 0.5)
a.push(v);
return a;
}
function randomPermutation$(x, n = -1, fr = Math.random) {
var X = x.length;
if (n > X)
return x;
var n = n >= 0 ? n : Math.floor((X + 1) * fr());
for (var i = 0; i < n; ++i) {
var j = i + Math.floor((X - i) * fr());
var t = x[i];
x[i] = x[j];
x[j] = t;
}
x.length = n;
return x;
}
function some$1(x, ft = null) {
if (ft)
return x.some(ft);
else
return someBoolean(x);
}
function someBoolean(x) {
for (var i = 0, I = x.length; i < I; ++i)
if (x[i])
return true;
return false;
}
function is(v) {
return v instanceof Map;
}
function keys(x) {
return x.keys();
}
function values(x) {
return x.values();
}
function entries(x) {
return x.entries();
}
function from(x) {
return new Map(x);
}
function from$(x) {
return x instanceof Map ? x : new Map(x);
}
function fromLists(x) {
var [ks, vs] = x;
var iv = vs[Symbol.iterator]();
var a = new Map();
for (var k of ks)
a.set(k, iv.next().value);
return a;
}
function fromKeys(x, fm = null) {
var fm = fm || IDENTITY;
var a = new Map(), i = -1;
for (var k of x)
a.set(k, fm(k, ++i, x));
return a;
}
function fromValues(x, fm = null) {
var fm = fm || IDENTITY;
var a = new Map(), i = -1;
for (var v of x)
a.set(fm(v, ++i, x), v);
return a;
}
function compare(x, y, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var ks = unionKeys(x, y);
for (var k of ks) {
if (!x.has(k))
return -1;
if (!y.has(k))
return 1;
var vx = fm(x.get(k), k, x);
var vy = fm(y.get(k), k, y);
var c = fc(vx, vy);
if (c !== 0)
return c;
}
return 0;
}
function isEqual(x, y, fc = null, fm = null) {
return x.size === y.size && compare(x, y, fc, fm) === 0;
}
function size(x) {
return x.size;
}
function isEmpty(x) {
return x.size === 0;
}
function get(x, k) {
return x.get(k);
}
function getAll(x, ks) {
return ks.map(k => x.get(k));
}
function getPath(x, p) {
for (var k of p)
x = is(x) ? x.get(k) : undefined;
return x;
}
function hasPath(x, p) {
for (var k of p) {
if (!is(x))
return false;
x = x.get(k);
}
return true;
}
function set(x, k, v) {
return new Map(x).set(k, v);
}
function set$(x, k, v) {
return x.set(k, v);
}
function setPath$(x, p, v) {
var y = getPath(x, p.slice(0, -1));
if (is(y))
y.set(last(p), v);
return x;
}
function swap(x, k, l) {
return swap$(new Map(x), k, l);
}
function swap$(x, k, l) {
var t = x.get(k);
x.set(k, x.get(l));
x.set(l, t);
return x;
}
function remove(x, k) {
return remove$(new Map(x), k);
}
function remove$(x, k) {
x.delete(k);
return x;
}
function removePath$(x, p) {
var y = getPath(x, p.slice(0, -1));
if (is(y))
y.delete(last(p));
return x;
}
function count(x, ft) {
var a = 0;
for (var [k, v] of x)
if (ft(v, k, x))
++a;
return a;
}
function countAs(x, fm = null) {
var fm = fm || IDENTITY;
var a = new Map();
for (var [k, v] of x) {
var w = fm(v, k, x);
var n = a.get(w) || 0;
a.set(w, n + 1);
}
return a;
}
function min(x, fc = null, fm = null) {
return rangeEntries(x, fc, fm)[0][1];
}
function minEntry(x, fc = null, fm = null) {
return rangeEntries(x, fc, fm)[0];
}
function max(x, fc = null, fm = null) {
return rangeEntries(x, fc, fm)[1][1];
}
function maxEntry(x, fc = null, fm = null) {
return rangeEntries(x, fc, fm)[1];
}
function range(x, fc = null, fm = null) {
var [a, b] = rangeEntries(x, fc, fm);
return [a[1], b[1]];
}
function rangeEntries(x, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var mk, mu, mv;
var nk, nu, nv;
var i = 0;
for (var [k, u] of x) {
var v = fm(u, k, x);
if (i === 0 || fc(v, mv) < 0) {
mk = k;
mu = u;
mv = v;
}
if (i === 0 || fc(v, nv) > 0) {
nk = k;
nu = u;
nv = v;
}
++i;
}
return [[mk, mu], [nk, nu]];
}
function head(x, ed = []) {
for (var e of x)
return e;
return ed;
}
function tail(x) {
return drop(x, 1);
}
function take(x, n = 1) {
var a = new Map(), i = -1;
for (var [k, v] of x) {
if (++i >= n)
break;
a.set(k, v);
}
return a;
}
function take$(x, n = 1) {
var i = -1;
for (var k of x.keys())
if (++i >= n)
x.delete(k);
return x;
}
function drop(x, n = 1) {
var a = new Map(), i = -1;
for (var [k, v] of x)
if (++i >= n)
a.set(k, v);
return a;
}
function drop$(x, n = 1) {
var i = -1;
for (var k of x.keys()) {
if (++i >= n)
break;
x.delete(k);
}
return x;
}
function* subsets(x, n = -1) {
for (var ks of subsequences([...x.keys()], n))
yield filterAt(x, ks);
}
function randomKey(x, fr = Math.random) {
return randomValue([...x.keys()], fr);
}
function randomEntry(x, fr = Math.random) {
return randomValue([...x], fr);
}
function randomSubset(x, n = -1, fr = Math.random) {
var ks = randomSubsequence([...x.keys()], n, fr);
return filterAt(x, ks);
}
function has(x, k) {
return x.has(k);
}
function hasValue(x, v, fc = null, fm = null) {
return searchValue(x, v, fc, fm) !== undefined;
}
function hasEntry(x, e, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var [k, v] = e;
return x.has(k) && fc(fm(x.get(k), k, x), v) === 0;
}
function hasSubset(x, y, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
for (var [k, v] of y) {
if (!x.has(k))
return false;
var wx = fm(x.get(k), k, x);
var wy = fm(v, k, y);
if (fc(wx, wy) !== 0)
return false;
}
return true;
}
function find(x, ft) {
for (var [k, v] of x)
if (ft(v, k, x))
return v;
}
function findAll(x, ft) {
var a = [];
for (var [k, v] of x)
if (ft(v, k, x))
a.push(v);
return a;
}
function search(x, ft) {
for (var [k, v] of x)
if (ft(v, k, x))
return k;
}
function searchAll(x, ft) {
var a = [];
for (var [k, v] of x)
if (ft(v, k, x))
a.push(k);
return a;
}
function searchValue(x, v, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var w = fm(v, null, null);
for (var [k, u] of x) {
var wx = fm(u, k, x);
if (fc(wx, w) === 0)
return k;
}
}
function searchValueAll(x, v, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var w = fm(v, null, null), a = [];
for (var [k, u] of x) {
var wx = fm(u, k, x);
if (fc(wx, w) === 0)
a.push(k);
}
return a;
}
function forEach(x, fp) {
for (var [k, v] of x)
fp(v, k, x);
}
function some(x, ft) {
for (var [k, v] of x)
if (ft(v, k, x))
return true;
return false;
}
function every(x, ft) {
for (var [k, v] of x)
if (!ft(v, k, x))
return false;
return true;
}
function map(x, fm) {
var a = new Map();
for (var [k, v] of x)
a.set(k, fm(v, k, x));
return a;
}
function map$(x, fm) {
for (var [k, v] of x)
x.set(k, fm(v, k, x));
return x;
}
function reduce(x, fr, acc) {
var init = arguments.length <= 2;
for (var [k, v] of x) {
if (init) {
acc = v;
init = false;
}
else
acc = fr(acc, v, k, x);
}
return acc;
}
function filter(x, ft) {
var a = new Map();
for (var [k, v] of x)
if (ft(v, k, x))
a.set(k, v);
return a;
}
function filter$(x, ft) {
for (var [k, v] of x)
if (!ft(v, k, x))
x.delete(k);
return x;
}
function filterAt(x, ks) {
var a = new Map();
for (var k of ks)
a.set(k, x.get(k));
return a;
}
function filterAt$(x, ks) {
for (var k of x.keys())
if (!ks.includes(k))
x.delete(k);
return x;
}
function reject(x, ft) {
var a = new Map();
for (var [k, v] of x)
if (!ft(v, k, x))
a.set(k, v);
return a;
}
function reject$(x, ft) {
for (var [k, v] of x)
if (ft(v, k, x))
x.delete(k);
return x;
}
function rejectAt(x, ks) {
return rejectAt$(new Map(x), ks);
}
function rejectAt$(x, ks) {
for (var k of ks)
x.delete(k);
return x;
}
function flat(x, n = -1, fm = null, ft = null) {
var fm = fm || IDENTITY;
var ft = ft || is;
return flatTo$(new Map(), x, n, fm, ft);
}
function flatTo$(a, x, n, fm, ft) {
for (var [k, v] of x) {
var w = fm(v, k, x);
if (n !== 0 && ft(w, k, x))
flatTo$(a, w, n - 1, fm, ft);
else
a.set(k, w);
}
return a;
}
function flatMap(x, fm = null, ft = null) {
var fm = fm || IDENTITY;
var ft = ft || is;
var a = new Map();
for (var [k, v] of x) {
var w = fm(v, k, x);
if (ft(w, k, x))
concat$(a, w);
else
a.set(k, w);
}
return a;
}
function zip(xs, fm = null, fe = null, vd) {
var fm = fm || IDENTITY;
var fe = fe || some$1;
var ks = unionKeys(...xs), a = new Map();
for (var k of ks) {
var ds = xs.map(x => !x.has(k));
if (fe(ds))
break;
var vs = xs.map(x => !x.has(k) ? vd : x.get(k));
a.set(k, fm(vs, k, null));
}
return a;
}
function partition(x, ft) {
var t = new Map();
var f = new Map();
for (var [k, v] of x) {
if (ft(v, k, x))
t.set(k, v);
else
f.set(k, v);
}
return [t, f];
}
function partitionAs(x, fm) {
var fm = fm || IDENTITY;
var a = new Map();
for (var [k, v] of x) {
var w = fm(v, k, x);
if (!a.has(w))
a.set(w, new Map());
a.get(w).set(k, v);
}
return a;
}
function chunk(x, n = 1, s = n) {
var ks = [...x.keys()], a = [];
for (var i = 0, I = ks.length; i < I; i += s)
a.push(filterAt(x, ks.slice(i, i + n)));
return a;
}
function concat(...xs) {
return concat$(new Map(), ...xs);
}
function concat$(x, ...ys) {
for (var y of ys) {
for (var [k, v] of y)
x.set(k, v);
}
return x;
}
function join(x, sep = ",", asc = "=") {
var a = "";
for (var [k, v] of x)
a += k + asc + v + sep;
return a.slice(0, -sep.length);
}
function isDisjoint(x, y) {
for (var [k] of y)
if (x.has(k))
return false;
return true;
}
function unionKeys(...xs) {
var a = new Set();
for (var x of xs) {
for (var [k] of x)
a.add(k);
}
return a;
}
function union(x, y, fc = null) {
return union$(new Map(x), y, fc);
}
function union$(x, y, fc = null) {
var fc = fc || IDENTITY;
for (var [k, v] of y) {
if (!x.has(k))
x.set(k, v);
else
x.set(k, fc(x.get(k), v));
}
return x;
}
function intersectionKeys(...xs) {
var a = new Set();
if (xs.length === 0)
return a;
var x = xs[0], ys = xs.slice(1);
LOOPX: for (var k of x.keys()) {
for (var y of ys)
if (!y.has(k))
continue LOOPX;
a.add(k);
}
return a;
}
function intersection(x, y, fc = null) {
var fc = fc || IDENTITY;
var a = new Map();
for (var [k, v] of y)
if (x.has(k))
a.set(k, fc(x.get(k), v));
return a;
}
function intersection$(x, y, fc = null) {
var fc = fc || IDENTITY, ks = [];
for (var [k, u] of [...x]) {
if (!y.has(k))
ks.push(k);
x.set(k, fc(u, y.get(k)));
}
return rejectAt$(x, ks);
}
function difference(x, y) {
return difference$(new Map(x), y);
}
function difference$(x, y) {
for (var [k] of y)
x.delete(k);
return x;
}
function symmetricDifference(x, y) {
return symmetricDifference$(new Map(x), y);
}
function symmetricDifference$(x, y) {
for (var [k, v] of y) {
if (x.has(k))
x.delete(k);
else
x.set(k, v);
}
return x;
}
function* cartesianProduct(xs, fm = null) {
var fm = fm || IDENTITY;
var XS = xs.length;
var kx = xs.map(x => [...x.keys()]);
var ls = kx.map(ks => ks.length);
var is = kx.map(ks => 0);
for (var j = 0;; ++j) {
var a = new Map();
for (var n = 0; n < XS; ++n) {
var i = is[n], x = xs[n];
var ks = kx[n], k = ks[i];
a.set(k, x.get(k));
}
yield fm(a, j, null);
for (var r = XS - 1; r >= 0; --r) {
if (++is[r] < ls[r])
break;
is[r] = 0;
}
if (r < 0)
break;
}
}
export { cartesianProduct, chunk, compare, concat, concat$, count, countAs, difference, difference$, drop, drop$, entries, randomEntry as entry, every, filter, filter$, filterAt, filterAt$, find, findAll, flat, flatMap, forEach, from, from$, from as fromEntries, from$ as fromEntries$, fromKeys, fromLists, fromValues, get, getAll, getPath, has, hasEntry, has as hasKey, hasPath, hasSubset, hasValue, head, intersection, intersection$, intersectionKeys, is, isDisjoint, isEmpty, isEqual, join, randomKey as key, keys, size as length, map, map$, max, maxEntry, min, minEntry, partition, partitionAs, randomEntry, randomKey, randomSubset, range, rangeEntries, reduce, reject, reject$, rejectAt, rejectAt$, remove, remove$, removePath$, search, searchAll, searchValue, searchValueAll, set, set$, setPath$, size, some, randomSubset as subset, subsets, swap, swap$, symmetricDifference, symmetricDifference$, tail, take, take$, union, union$, unionKeys, values, zip };