-
-
Save ssippe/1f92625532eef28be6974f898efb23ef to your computer and use it in GitHub Desktop.
| 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); | |
| }; |
Tell me that you cannot solve the problem of the cartesian product in TypeScript without telling me that you cannot solve the problem of the cartesian product in TypeScript.
Which is fine, by the way. I don't know the solution either. I came here looking for the solution and make the note that the proposed solution is wrong, in the sense explained in the comment above. Nothing else.
If you find the right solution, I'd be glad if you posted it here.
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())))@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(),
)
)
);That solution actually works!
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()),
),
);
const numbers = [1, 2, 3, 4];
const strings = ["1", "2", "3", "4"];
// const product: [number, string][]
const product = cartesianProduct([numbers, strings]);
console.log(product[0][1].length);Thanks @please-rewrite , @h-chal ! The only awkward thing is that we must use any, but apart from that, this gets the job done :D
@cr0cK now you can compare your non-functioning solution with an actually working solution :)
Indeed, the inference does not work with your example.
But my simple recommendation here:
Try to avoid mixing types when you can. Here for a cartesian product, I'm not sure it makes a lot of sense to mix strings and numbers.
A type system is also here to help you to design things the right way. If the implementation becomes too complex, it generally means that something is wrong. You do not implement things the same way when using typings. If you're not happy with that, you should go back to JS.