97 lines
2.3 KiB
JavaScript
97 lines
2.3 KiB
JavaScript
/**
|
|
* Iterate of all possible combinations of the given options.
|
|
* @example
|
|
* ```typescript
|
|
* for (const {a, b} of optionsMatrix({a: [1, 2], b: ["x", "y"]}))
|
|
* console.log(a, b);
|
|
* ```
|
|
*
|
|
* Will output:
|
|
* ```txt
|
|
* 1 x
|
|
* 1 y
|
|
* 2 x
|
|
* 2 y
|
|
* ```
|
|
*/
|
|
export function* optionsMatrix(options) {
|
|
const keys = Object.keys(options);
|
|
const indexes = keys.map(() => 0);
|
|
while (true) {
|
|
const result = {};
|
|
for (let i = 0; i < keys.length; i++) {
|
|
const key = keys[i];
|
|
const keyOptions = options[key];
|
|
result[key] = keyOptions[indexes[i]];
|
|
}
|
|
yield result;
|
|
let moved = false;
|
|
for (let i = keys.length - 1; i >= 0; i--) {
|
|
const key = keys[i];
|
|
const keyOptions = options[key];
|
|
if (indexes[i] >= keyOptions.length - 1) {
|
|
if (i === 0)
|
|
return;
|
|
indexes[i] = 0;
|
|
}
|
|
else if (indexes[i] < keyOptions.length - 1) {
|
|
indexes[i]++;
|
|
moved = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!moved)
|
|
return;
|
|
}
|
|
}
|
|
/**
|
|
* Iterate of all possible combinations of the given options and call the callback with each combination.
|
|
*
|
|
* The result of the first combination that doesn't throw an error will be returned as the result of this function.
|
|
*
|
|
* If all combinations throw an error, the error of the last combination will be thrown.
|
|
* @example
|
|
* ```typescript
|
|
* const result = tryMatrix({
|
|
* a: [1, 2],
|
|
* b: ["x", "y"]
|
|
* }, ({a, b}) => {
|
|
* console.log(a, b);
|
|
*
|
|
* if (a === 2 && b === "y")
|
|
* return `success ${a} ${b}`;
|
|
*
|
|
* throw new Error("fail");
|
|
* });
|
|
*
|
|
* console.log(result);
|
|
* ```
|
|
*
|
|
* Will output:
|
|
* ```txt
|
|
* 1 x
|
|
* 1 y
|
|
* 2 x
|
|
* 2 y
|
|
* success 2 y
|
|
* ```
|
|
*/
|
|
export function tryMatrix(options, callback) {
|
|
let nextOption = undefined;
|
|
for (const option of optionsMatrix(options)) {
|
|
if (nextOption == null) {
|
|
nextOption = option;
|
|
continue;
|
|
}
|
|
try {
|
|
return callback(nextOption);
|
|
}
|
|
catch (err) {
|
|
nextOption = option;
|
|
}
|
|
}
|
|
if (nextOption != null)
|
|
return callback(nextOption);
|
|
throw new Error("All options failed");
|
|
}
|
|
//# sourceMappingURL=optionsMatrix.js.map
|