extra-object
Version:
A collection of methods for working with Objects.
865 lines (860 loc) • 19.8 kB
JavaScript
'use strict';
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) {
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* subsequences(y, n);
for (var s of subsequences(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;
}
const BAD_KEYS = ["__proto__", "prototype", "constructor"];
function is(v) {
return typeof v === "object";
}
function keys(x) {
return Object.keys(x);
}
function values(x) {
return Object.values(x);
}
function entries(x) {
return Object.entries(x);
}
function fromEntries(x) {
var a = {};
for (var [k, v] of x)
a[k] = v;
return a;
}
function fromLists(x) {
var [ks, vs] = x, a = {};
var iv = vs[Symbol.iterator]();
for (var k of ks)
a[k] = iv.next().value;
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.hasOwnProperty(k))
return -1;
if (!y.hasOwnProperty(k))
return 1;
var wx = fm(x[k], k, x);
var wy = fm(y[k], k, y);
var c = fc(wx, wy);
if (c !== 0)
return c;
}
return 0;
}
function isEqual(x, y, fc = null, fm = null) {
return compare(x, y, fc, fm) === 0;
}
function size(x) {
return Object.keys(x).length;
}
function isEmpty(x) {
return size(x) === 0;
}
function get(x, k) {
return x[k];
}
function getAll(x, ks) {
return ks.map(k => x[k]);
}
function getPath(x, p) {
for (var k of p)
x = is(x) && !BAD_KEYS.includes(k) ? x[k] : undefined;
return x;
}
function hasPath(x, p) {
for (var k of p) {
if (!is(x))
return false;
x = x[k];
}
return true;
}
function set(x, k, v) {
return set$(Object.assign({}, x), k, v);
}
function set$(x, k, v) {
x[k] = v;
return x;
}
function setPath$(x, p, v) {
var y = getPath(x, p.slice(0, -1));
var k = last(p, "");
if (is(y) && k && !BAD_KEYS.includes(k))
y[k] = v;
return x;
}
function swap(x, k, l) {
return swap$(Object.assign({}, x), k, l);
}
function swap$(x, k, l) {
var t = x[k];
x[k] = x[l];
x[l] = t;
return x;
}
function remove(x, k) {
var a = {};
for (var l in x) {
if (!x.hasOwnProperty(k))
continue;
if (l !== k)
a[l] = x[l];
}
return a;
}
function remove$(x, k) {
delete x[k];
return x;
}
function removePath$(x, p) {
var y = getPath(x, p.slice(0, -1));
var k = last(p, "");
if (is(y) && k)
delete y[k];
return x;
}
function count(x, ft) {
var a = 0;
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (ft(x[k], k, x))
++a;
}
return a;
}
function countAs(x, fm = null) {
var fm = fm || (IDENTITY);
var a = new Map();
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
var w = fm(x[k], 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 in x) {
if (!x.hasOwnProperty(k))
continue;
var u = x[k], 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 k in x) {
if (!x.hasOwnProperty(k))
continue;
return [k, x[k]];
}
return ed;
}
function tail(x) {
return drop(x, 1);
}
function take(x, n = 1) {
var i = -1, a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (++i >= n)
break;
a[k] = x[k];
}
return a;
}
function take$(x, n = 1) {
var i = -1;
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (++i >= n)
delete x[k];
}
return x;
}
function drop(x, n = 1) {
var i = -1, a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (++i >= n)
a[k] = x[k];
}
return a;
}
function drop$(x, n = 1) {
var i = -1;
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (++i >= n)
break;
delete x[k];
}
return x;
}
function* subsets(x, n = -1) {
for (var ks of subsequences(Object.keys(x), n))
yield filterAt(x, ks);
}
function randomKey(x, fr = Math.random) {
return randomValue(Object.keys(x), fr);
}
function randomEntry(x, fr = Math.random) {
return randomValue(Object.entries(x), fr);
}
function randomSubset(x, n = -1, fr = Math.random) {
var ks = randomSubsequence(Object.keys(x), n, fr);
return filterAt(x, ks);
}
function has(x, k) {
return x.hasOwnProperty(k);
}
function hasValue(x, v, fc = null, fm = null) {
return searchValue(x, v, fc, fm) != null;
}
function hasEntry(x, e, fc = null, fm = null) {
var fc = fc || (COMPARE);
var fm = fm || (IDENTITY);
var [k, v] = e;
return x.hasOwnProperty(k) && fc(fm(x[k], k, x), v) === 0;
}
function hasSubset(x, y, fc = null, fm = null) {
var fc = fc || (COMPARE);
var fm = fm || (IDENTITY);
for (var k of Object.keys(y)) {
if (!x.hasOwnProperty(k))
return false;
var wx = fm(x[k], k, x);
var wy = fm(y[k], k, y);
if (fc(wx, wy) !== 0)
return false;
}
return true;
}
function find(x, ft) {
for (var k of Object.keys(x))
if (ft(x[k], k, x))
return x[k];
}
function findAll(x, ft) {
var a = [];
for (var k of Object.keys(x))
if (ft(x[k], k, x))
a.push(x[k]);
return a;
}
function search(x, ft) {
for (var k of Object.keys(x))
if (ft(x[k], k, x))
return k;
return null;
}
function searchAll(x, ft) {
var a = [];
for (var k of Object.keys(x))
if (ft(x[k], 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 of Object.keys(x)) {
var wx = fm(x[k], k, x);
if (fc(wx, w) === 0)
return k;
}
return null;
}
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 of Object.keys(x)) {
var wx = fm(x[k], k, x);
if (fc(wx, w) === 0)
a.push(k);
}
return a;
}
function forEach(x, fp) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
fp(x[k], k, x);
}
}
function some(x, ft = null) {
var ft = ft || IDENTITY;
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (ft(x[k], k, x))
return true;
}
return false;
}
function every(x, ft) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!ft(x[k], k, x))
return false;
}
return true;
}
function map(x, fm) {
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
a[k] = fm(x[k], k, x);
}
return a;
}
function map$(x, fm) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
x[k] = fm(x[k], k, x);
}
return x;
}
function reduce(x, fr, acc) {
var init = arguments.length <= 2;
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (init) {
acc = x[k];
init = false;
}
else
acc = fr(acc, x[k], k, x);
}
return acc;
}
function filter(x, ft) {
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (ft(x[k], k, x))
a[k] = x[k];
}
return a;
}
function filter$(x, ft) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!ft(x[k], k, x))
delete x[k];
}
return x;
}
function filterAt(x, ks) {
var a = {};
for (var k of ks)
if (x.hasOwnProperty(k))
a[k] = x[k];
return a;
}
function filterAt$(x, ks) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!ks.includes(k))
delete x[k];
}
return x;
}
function reject(x, ft) {
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!ft(x[k], k, x))
a[k] = x[k];
}
return a;
}
function reject$(x, ft) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (ft(x[k], k, x))
delete x[k];
}
return x;
}
function rejectAt(x, ks) {
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!ks.includes(k))
a[k] = x[k];
}
return a;
}
function rejectAt$(x, ks) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (ks.includes(k))
delete x[k];
}
return x;
}
function flat(x, n = -1, fm = null, ft = null) {
var fm = fm || (IDENTITY);
var ft = ft || is;
return flatTo$({}, x, n, fm, ft);
}
function flatTo$(a, x, dep, fm, ft) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
var w = fm(x[k], k, x);
if (dep !== 0 && ft(w, k, x))
flatTo$(a, w, dep - 1, fm, ft);
else
a[k] = w;
}
return a;
}
function flatMap(x, fm = null, ft = null) {
var fm = fm || (IDENTITY);
var ft = ft || is;
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
var w = fm(x[k], k, x);
if (ft(w, k, x))
Object.assign(a, w);
else
a[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 = {};
for (var k of ks) {
var ds = xs.map(x => !x.hasOwnProperty(k));
if (fe(ds))
break;
var vs = xs.map(x => !x.hasOwnProperty(k) ? vd : x[k]);
a[k] = fm(vs, k, null);
}
return a;
}
function partition(x, ft) {
var t = {}, f = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (ft(x[k], k, x))
t[k] = x[k];
else
f[k] = x[k];
}
return [t, f];
}
function partitionAs(x, fm) {
var fm = fm || (IDENTITY);
var a = new Map();
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
var w = fm(x[k], k, x);
if (!a.has(w))
a.set(w, {});
a.get(w)[k] = x[k];
}
return a;
}
function chunk(x, n = 1, s = n) {
var ks = Object.keys(x), 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 Object.assign({}, ...xs);
}
function concat$(x, ...ys) {
return Object.assign(x, ...ys);
}
function join(x, sep = ",", asc = "=") {
var a = "";
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
a += k + asc + x[k] + sep;
}
return a.slice(0, -sep.length);
}
function isDisjoint(x, y) {
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (y.hasOwnProperty(k))
return false;
}
return true;
}
function unionKeys(...xs) {
var a = new Set();
for (var x of xs) {
for (var k in x)
if (x.hasOwnProperty(k))
a.add(k);
}
return a;
}
function union(x, y, fc = null) {
return union$(Object.assign({}, x), y, fc);
}
function union$(x, y, fc = null) {
var fc = fc || IDENTITY;
for (var k in y) {
if (!y.hasOwnProperty(k))
continue;
if (!x.hasOwnProperty(k))
x[k] = y[k];
else
x[k] = fc(x[k], y[k]);
}
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 in x) {
if (!x.hasOwnProperty(k))
continue;
for (var y of ys)
if (!y.hasOwnProperty(k))
continue LOOPX;
a.add(k);
}
return a;
}
function intersection(x, y, fc = null) {
var fc = fc || IDENTITY;
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!y.hasOwnProperty(k))
continue;
a[k] = fc(x[k], y[k]);
}
return a;
}
function intersection$(x, y, fc = null) {
var fc = fc || IDENTITY;
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!y.hasOwnProperty(k))
delete x[k];
else
x[k] = fc(x[k], y[k]);
}
return x;
}
function difference(x, y) {
var a = {};
for (var k in x) {
if (!x.hasOwnProperty(k))
continue;
if (!y.hasOwnProperty(k))
a[k] = x[k];
}
return a;
}
function difference$(x, y) {
for (var k in y) {
if (!y.hasOwnProperty(k))
continue;
if (x.hasOwnProperty(k))
delete x[k];
}
return x;
}
function symmetricDifference(x, y) {
var a = {};
for (var k of unionKeys(x, y)) {
var xk = x.hasOwnProperty(k);
var yk = y.hasOwnProperty(k);
if (xk && !yk)
a[k] = x[k];
else if (!xk && yk)
a[k] = y[k];
}
return a;
}
function symmetricDifference$(x, y) {
for (var k in y) {
if (!y.hasOwnProperty(k))
continue;
if (x.hasOwnProperty(k))
delete x[k];
else
x[k] = y[k];
}
return x;
}
function* cartesianProduct(xs, fm = null) {
var fm = fm || (IDENTITY);
var XS = xs.length;
var kx = xs.map(x => Object.keys(x));
var ls = kx.map(ks => ks.length);
var is = kx.map(ks => 0);
while (true) {
var a = {};
for (var n = 0; n < XS; ++n) {
var i = is[n], x = xs[n];
var ks = kx[n], k = ks[i];
a[k] = x[k];
}
yield fm(a, null, null);
for (var r = XS - 1; r >= 0; --r) {
if (++is[r] < ls[r])
break;
is[r] = 0;
}
if (r < 0)
break;
}
}
exports.cartesianProduct = cartesianProduct;
exports.chunk = chunk;
exports.compare = compare;
exports.concat = concat;
exports.concat$ = concat$;
exports.count = count;
exports.countAs = countAs;
exports.difference = difference;
exports.difference$ = difference$;
exports.drop = drop;
exports.drop$ = drop$;
exports.entries = entries;
exports.entry = randomEntry;
exports.every = every;
exports.filter = filter;
exports.filter$ = filter$;
exports.filterAt = filterAt;
exports.filterAt$ = filterAt$;
exports.find = find;
exports.findAll = findAll;
exports.flat = flat;
exports.flatMap = flatMap;
exports.forEach = forEach;
exports.fromEntries = fromEntries;
exports.fromLists = fromLists;
exports.get = get;
exports.getAll = getAll;
exports.getPath = getPath;
exports.has = has;
exports.hasEntry = hasEntry;
exports.hasKey = has;
exports.hasPath = hasPath;
exports.hasSubset = hasSubset;
exports.hasValue = hasValue;
exports.head = head;
exports.intersection = intersection;
exports.intersection$ = intersection$;
exports.intersectionKeys = intersectionKeys;
exports.is = is;
exports.isDisjoint = isDisjoint;
exports.isEmpty = isEmpty;
exports.isEqual = isEqual;
exports.join = join;
exports.key = randomKey;
exports.keys = keys;
exports.length = size;
exports.map = map;
exports.map$ = map$;
exports.max = max;
exports.maxEntry = maxEntry;
exports.min = min;
exports.minEntry = minEntry;
exports.partition = partition;
exports.partitionAs = partitionAs;
exports.randomEntry = randomEntry;
exports.randomKey = randomKey;
exports.randomSubset = randomSubset;
exports.range = range;
exports.rangeEntries = rangeEntries;
exports.reduce = reduce;
exports.reject = reject;
exports.reject$ = reject$;
exports.rejectAt = rejectAt;
exports.rejectAt$ = rejectAt$;
exports.remove = remove;
exports.remove$ = remove$;
exports.removePath$ = removePath$;
exports.search = search;
exports.searchAll = searchAll;
exports.searchValue = searchValue;
exports.searchValueAll = searchValueAll;
exports.set = set;
exports.set$ = set$;
exports.setPath$ = setPath$;
exports.size = size;
exports.some = some;
exports.subset = randomSubset;
exports.subsets = subsets;
exports.swap = swap;
exports.swap$ = swap$;
exports.symmetricDifference = symmetricDifference;
exports.symmetricDifference$ = symmetricDifference$;
exports.tail = tail;
exports.take = take;
exports.take$ = take$;
exports.union = union;
exports.union$ = union$;
exports.unionKeys = unionKeys;
exports.values = values;
exports.zip = zip;