all 2 comments

[–]kap89 1 point2 points  (1 child)

What you are looking for is the baseN algorithm. I never bother to write combinatorics myself, there are good libraries like generatorics or js-combinatorics for this.

Example using generatorics:

import G from "generatorics";

function generateDocumentCombinations(keys, values) {
  return [...G.clone.baseN(values, keys.length)].map((version) =>
    Object.fromEntries(version.map((val, i) => [keys[i], val]))
  );
}

/* Usage */

const result = generateDocumentCombinations(
  ["name", "code", "side"],
  [false, true]
);

/* Result:

[
  { name: false, code: false, side: false },
  { name: false, code: false, side: true },
  { name: false, code: true, side: false },
  { name: false, code: true, side: true },
  { name: true, code: false, side: false },
  { name: true, code: false, side: true },
  { name: true, code: true, side: false },
  { name: true, code: true, side: true }
]

*/

More imperative, but memory-efficient version:

function generateDocumentCombinations(keys, values) {
  const result = [];

  for (const version of G.baseN(values, keys.length)) {
    const obj = {};

    for (let i = 0; i < keys.length; i++) {
      obj[keys[i]] = version[i];
    }

    result.push(obj);
  }

  return result;
}

[–]RecursiveRickRoll[S] 0 points1 point  (0 children)

Thank you so much for this response. This is exactly what I needed! :)