Skip to content

Instantly share code, notes, and snippets.

@ssippe
Created April 20, 2017 00:33
Show Gist options
  • Select an option

  • Save ssippe/1f92625532eef28be6974f898efb23ef to your computer and use it in GitHub Desktop.

Select an option

Save ssippe/1f92625532eef28be6974f898efb23ef to your computer and use it in GitHub Desktop.
Typescript Cartesian Product
const f = (a: any[], b: any[]): any[] =>
[].concat(...a.map(a2 => b.map(b2 => [].concat(a2, b2))));
export const cartesianProduct = (a: any[], b: any[], ...c: any[]) => {
if (!b || b.length === 0) {
return a;
}
const [b2, ...c2] = c;
const fab = f(a, b);
return cartesianProduct(fab, b2, c2);
};
@please-rewrite
Copy link

please-rewrite commented Oct 31, 2023

Mixed types are tricky.
Give this a try.

The key is [...T]

export const cartesianProduct = <T extends any[][]>(a: [...T]): Array<{[K in keyof T]: T[K][number]}> => a.reduce((a, b) => a.flatMap(d => b.map(e => [d, e].flat())))

@h-chal
Copy link

h-chal commented Dec 10, 2025

@please-rewrite 's version with clearer variable names:

export const cartesianProduct = <T extends any[][]>(
    arrays: [...T],
): Array<{ [K in keyof T]: T[K][number]; }> =>
    arrays.reduce((partialProduct, nextArray) =>
        partialProduct.flatMap(items =>
            nextArray.map(
                nextItem => [items, nextItem].flat(),
            )
        )
    );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment