JSFiddle - React, Tailwind, and code Playground
HTML
<div id="output"></div>
JavaScript
'use strict';
function* product(...seqs) {
const indices = seqs.map(() => 0),
lengths = seqs.map(seq => seq.length);
if (lengths.indexOf(0) != -1) {
return;
}
while (true) {
yield indices.map((i, iseq) => seqs[iseq][i]);
// Update indices right-to-left
let i;
for (i = indices.length - 1; i >= 0; i--) {
indices[i]++;
if (indices[i] == lengths[i]) {
// roll-over
indices[i] = 0;
} else {
break;
}
}
// If i is negative, then all indices have rolled-over
if (i < 0) {
break;
}
}
}
function join(keys, values) {
const lookup = [...new Set(keys)].reduce((o, k) => {
o[k] = [];
return o;
}, {});
// Iterate over array indices instead of objects them selves
for (let i of values.keys()) {
const k = Object.keys(values[i])[0];
if (lookup.hasOwnProperty(k)) {
lookup[k].push(i);
}
}
return product(...keys.map(k => lookup[k]));
}
function isUniq(it, seen) {
const notHadIt = !seen.has(it);
if (notHadIt) {
seen.add(it);
}
return notHadIt;
}
function* removeDups(iterable) {
const seen = new Set();
skip: for (let it of iterable) {
seen.clear();
for (let x of it) {
if (!isUniq(x, seen)) {
continue skip;
}
}
yield it;
}
}
function* distinct(iterable) {
const seen = new Set();
for (let it of iterable) {
// Bit of a hack here, produce a known order for each row so
// that we can produce a "set of sets" as output. Rows are
// arrays of integers.
const k = it.sort().join();
if (isUniq(k, seen)) {
yield it;
}
}
}
function* query(input, arr) {
for (let it of distinct(removeDups(join(input, arr)))) {
// Objects from...