@thi.ng/associative
Version:
ES Map/Set-compatible implementations with customizable equality semantics & supporting operations
66 lines (65 loc) • 1.6 kB
JavaScript
import { commonKeysObj } from "@thi.ng/object-utils/common-keys";
import { empty } from "@thi.ng/object-utils/empty";
import { invertObj } from "@thi.ng/object-utils/invert";
import { mergeObj } from "@thi.ng/object-utils/merge";
import { renameKeysObj } from "@thi.ng/object-utils/rename-keys";
import { selectKeysObj } from "@thi.ng/object-utils/select-keys";
import { first } from "./first.js";
import { indexed } from "./indexed.js";
const join = (a, b) => {
if (a.size && b.size) {
const ks = commonKeysObj(first(a) || {}, first(b) || {});
let aa, bb;
if (a.size <= b.size) {
aa = a;
bb = b;
} else {
aa = b;
bb = a;
}
const idx = indexed(aa, ks);
const res = empty(a, Set);
for (let x of bb) {
const found = idx.get(selectKeysObj(x, ks));
if (found) {
for (let f of found) {
res.add(mergeObj({ ...f }, x));
}
}
}
return res;
}
return empty(a, Set);
};
const joinWith = (a, b, kmap) => {
if (a.size && b.size) {
let aa, bb;
let k;
if (a.size <= b.size) {
aa = a;
bb = b;
k = invertObj(kmap);
} else {
aa = b;
bb = a;
k = kmap;
}
const idx = indexed(aa, Object.values(k));
const ks = Object.keys(k);
const res = empty(a, Set);
for (let x of bb) {
const found = idx.get(renameKeysObj(selectKeysObj(x, ks), k));
if (found) {
for (let f of found) {
res.add(mergeObj({ ...f }, x));
}
}
}
return res;
}
return empty(a, Set);
};
export {
join,
joinWith
};