43 lines
1.4 KiB
JavaScript
Executable File
43 lines
1.4 KiB
JavaScript
Executable File
// Full credit goes to: https://github.com/purplestone/exhaust
|
|
// However, it is modified so that it is a bit more modern
|
|
export function produce(blueprint) {
|
|
let groups = []
|
|
|
|
// Call the blueprint once so that we can collect all the possible values we
|
|
// spit out in the callback function.
|
|
blueprint((...args) => {
|
|
if (args.length <= 0) throw new Error('Blueprint callback must have at least a single value')
|
|
groups.push(args)
|
|
})
|
|
|
|
// Calculate how many combinations there are
|
|
let iterations = groups.reduce((total, current) => total * current.length, 1)
|
|
|
|
// Calculate all the combinations possible
|
|
let zippedGroups = []
|
|
let currentIteration = iterations
|
|
groups.forEach((a) => {
|
|
let n = a.length
|
|
currentIteration = currentIteration / n
|
|
let iS = -1
|
|
let aS = []
|
|
|
|
for (let i = 0; i < iterations; i++) {
|
|
if (!(i % currentIteration)) iS++
|
|
aS.push(a[iS % n])
|
|
}
|
|
zippedGroups.push(aS)
|
|
})
|
|
|
|
// Transpose the matrix, so that we can get the correct rows/columns structure
|
|
// again.
|
|
zippedGroups = zippedGroups[0].map((_, i) => zippedGroups.map((o) => o[i]))
|
|
|
|
// Call the blueprint again, but now give the inner function a single value
|
|
// every time so that we can build up the final result with single values.
|
|
return zippedGroups.map((group) => {
|
|
let i = 0
|
|
return blueprint(() => group[i++])
|
|
})
|
|
}
|