extra-set
Version:
A pack of functions for working with Sets.
480 lines (476 loc) • 10.6 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(x, i) {
return x[index(x, i)];
}
function getAll(x, is) {
return is.map(i => get(x, i));
}
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$1(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(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 chunk$1(x, n = 1, s = n) {
var a = [];
if (n < 0)
return a;
var s = Math.max(s, 1);
for (var i = 0, I = x.length; i < I; i += s)
a.push(x.slice(i, i + n));
return a;
}
function is(v) {
return v instanceof Set;
}
function values(x) {
return x.values();
}
function entries(x) {
return x.entries();
}
function from(x, fm = null) {
if (!fm)
return new Set(x);
var a = new Set(), i = -1;
for (var v of x)
a.add(fm(v, ++i, x));
return a;
}
function from$(x) {
return x instanceof Set ? x : new Set(x);
}
function compare(x, y) {
for (var v of x)
if (!y.has(v))
return 1;
for (var v of y)
if (!x.has(v))
return -1;
return 0;
}
function isEqual(x, y) {
return x.size === y.size && compare(x, y) === 0;
}
function size(x) {
return x.size;
}
function isEmpty(x) {
return x.size === 0;
}
function add(x, v) {
return new Set(x).add(v);
}
function add$(x, v) {
return x.add(v);
}
function remove(x, v) {
return remove$(new Set(x), v);
}
function remove$(x, v) {
x.delete(v);
return x;
}
function count(x, ft) {
var a = 0;
for (var v of x)
if (ft(v, v, x))
++a;
return a;
}
function countAs(x, fm) {
var fm = fm || IDENTITY;
var a = new Map();
for (var v of x) {
var w = fm(v, v, x);
var n = a.get(w) || 0;
a.set(w, n + 1);
}
return a;
}
function min(x, fc = null, fm = null) {
return range(x, fc, fm)[0];
}
function max(x, fc = null, fm = null) {
return range(x, fc, fm)[1];
}
function range(x, fc = null, fm = null) {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var mu, mv;
var nu, nv;
var i = 0;
for (var u of x) {
var v = fm(u, u, x);
if (i === 0 || fc(v, mv) < 0) {
mu = u;
mv = v;
}
if (i === 0 || fc(v, nv) > 0) {
nu = u;
nv = v;
}
i++;
}
return [mu, nu];
}
function head(x, vd) {
for (var v of x)
return v;
return vd;
}
function tail(x) {
return drop(x, 1);
}
function take(x, n = 1) {
var a = new Set(), i = -1;
for (var v of x) {
if (++i >= n)
break;
a.add(v);
}
return a;
}
function take$(x, n = 1) {
var i = -1;
for (var v of x)
if (++i >= n)
x.delete(v);
return x;
}
function drop(x, n = 1) {
var a = new Set(), i = -1;
for (var v of x)
if (++i >= n)
a.add(v);
return a;
}
function drop$(x, n = 1) {
var i = -1;
for (var v of x) {
if (++i >= n)
break;
x.delete(v);
}
return x;
}
function* subsets(x, n = -1) {
for (var vs of subsequences([...x], n))
yield new Set(vs);
}
function randomValue(x, fr = Math.random) {
return randomValue$1([...x], fr);
}
function randomEntry(x, fr = Math.random) {
return randomValue$1([...x.entries()], fr);
}
function randomSubset(x, n = -1, fr = Math.random) {
var vs = randomSubsequence([...x], n, fr);
return new Set(vs);
}
function hasSubset(x, y) {
for (var v of y)
if (!x.has(v))
return false;
return true;
}
function has(x, v) {
return x.has(v);
}
function find(x, ft) {
for (var v of x)
if (ft(v, v, x))
return v;
}
function findAll(x, ft) {
var a = [];
for (var v of x)
if (ft(v, v, x))
a.push(v);
return a;
}
function forEach(x, fp) {
for (var v of x)
fp(v, v, x);
}
function some(x, ft = null) {
var ft = ft || IDENTITY;
for (var v of x)
if (ft(v, v, x))
return true;
return false;
}
function every(x, ft = null) {
var ft = ft || IDENTITY;
for (var v of x)
if (!ft(v, v, x))
return false;
return true;
}
function map(x, fm) {
var a = new Set();
for (var v of x)
a.add(fm(v, v, x));
return a;
}
function map$(x, fm) {
var vs = [];
for (var v of x)
vs.push(fm(v, v, x));
x.clear();
return concat$(x, vs);
}
function reduce(x, fr, acc) {
var init = arguments.length <= 2;
for (var v of x) {
if (init) {
acc = v;
init = false;
}
else
acc = fr(acc, v, v, x);
}
return acc;
}
function filter(x, ft) {
var a = new Set();
for (var v of x)
if (ft(v, v, x))
a.add(v);
return a;
}
function filter$(x, ft) {
for (var v of x)
if (!ft(v, v, x))
x.delete(v);
return x;
}
function reject(x, ft) {
var a = new Set();
for (var v of x)
if (!ft(v, v, x))
a.add(v);
return a;
}
function reject$(x, ft) {
for (var v of x)
if (ft(v, v, x))
x.delete(v);
return x;
}
function flat(x, n = -1, fm = null, ft = null) {
var fm = fm || IDENTITY;
var ft = ft || is;
return flatTo$(new Set(), x, n, fm, ft);
}
function flatTo$(a, x, n, fm, ft) {
for (var v of x) {
var v1 = fm(v, v, x);
if (n !== 0 && ft(v1, v1, x))
flatTo$(a, v1, n - 1, fm, ft);
else
a.add(v1);
}
return a;
}
function flatMap(x, fm = null, ft = null) {
var fm = fm || IDENTITY;
var ft = ft || is;
var a = new Set();
for (var v of x) {
var w = fm(v, v, x);
if (ft(w, w, x))
concat$(a, w);
else
a.add(w);
}
return a;
}
function partition(x, ft) {
var t = new Set();
var f = new Set();
for (var v of x) {
if (ft(v, v, x))
t.add(v);
else
f.add(v);
}
return [t, f];
}
function partitionAs(x, fm) {
var fm = fm || IDENTITY;
var a = new Map();
for (var v of x) {
var v1 = fm(v, v, x);
if (!a.has(v1))
a.set(v1, new Set());
a.get(v1).add(v);
}
return a;
}
function chunk(x, n = 1, s = n) {
return chunk$1([...x], n, s).map(c => new Set(c));
}
function concat(...xs) {
return concat$(new Set(), ...xs);
}
function concat$(x, ...ys) {
for (var y of ys) {
for (var v of y)
x.add(v);
}
return x;
}
function join(x, sep = ",") {
return [...x].join(sep);
}
function isDisjoint(x, y) {
for (var v of y)
if (x.has(v))
return false;
return true;
}
function union(x, y) {
return concat$(new Set(), x, y);
}
function union$(x, y) {
return concat$(x, y);
}
function intersection(x, y) {
var a = new Set();
for (var v of y)
if (x.has(v))
a.add(v);
return a;
}
function intersection$(x, y) {
for (var v of x)
if (!y.has(v))
x.delete(v);
return x;
}
function difference(x, y) {
var a = new Set();
for (var v of x)
if (!y.has(v))
a.add(v);
return a;
}
function difference$(x, y) {
for (var v of y)
x.delete(v);
return x;
}
function symmetricDifference(x, y) {
var a = new Set();
for (var v of x)
if (!y.has(v))
a.add(v);
for (var v of y)
if (!x.has(v))
a.add(v);
return a;
}
function symmetricDifference$(x, y) {
for (var v of y) {
if (x.has(v))
x.delete(v);
else
x.add(v);
}
return x;
}
function* cartesianProduct(xs, fm = null) {
var fm = fm || IDENTITY;
var XS = xs.length;
var ys = xs.map(x => [...x]);
var ls = ys.map(vs => vs.length);
var is = ys.map(vs => 0);
while (true) {
var a = new Set();
for (var n = 0; n < XS; ++n) {
var i = is[n];
var vs = ys[n], v = vs[i];
a.add(v);
}
yield fm(a, a, null);
for (var r = XS - 1; r >= 0; --r) {
if (++is[r] < ls[r])
break;
is[r] = 0;
}
if (r < 0)
break;
}
}
export { add, add$, cartesianProduct, chunk, compare, concat, concat$, count, countAs, cartesianProduct as default, difference, difference$, drop, drop$, entries, randomEntry as entry, every, filter, filter$, find, findAll, flat, flatMap, forEach, from, from$, has, hasSubset, head, intersection, intersection$, is, isDisjoint, isEmpty, isEqual, join, randomValue as key, values as keys, size as length, map, map$, max, min, partition, partitionAs, randomEntry, randomValue as randomKey, randomSubset, randomValue, range, reduce, reject, reject$, remove, remove$, find as search, findAll as searchAll, size, some, subsets, symmetricDifference, symmetricDifference$, tail, take, take$, union, union$, randomValue as value, values };