Consider following arrays:
var array1 = [true, false];
var array2 = [1, 2];
var array3 = ["a", "b", "c"];
I want to call my function myFunc(arg1, arg2, arg3)
with all argument combinations. But I want to avoid to "foreach" hell.
Is it possible write function that allows me that, so i can call it some like:
cartesianCall(array1, array2, array3, myFunc);
ideally with variable count of arrays (myFunc arguments)?
EDIT: so function would be called:
myFunc(true, 1, "a");
myFunc(true, 1, "b");
myFunc(true, 1, "c");
myFunc(true, 2, "a");
myFunc(true, 2, "b");
myFunc(true, 2, "c");
myFunc(false, 1, "a");
myFunc(false, 1, "b");
myFunc(false, 1, "c");
myFunc(false, 2, "a");
myFunc(false, 2, "b");
myFunc(false, 2, "c");
Declare you function without parameters and use arguments
keyword:
function cartesianCall() {
for (var i = 0; i < arguments.length; i++) {
// do something with arguments[i]
}
}
http://jsfiddle.net/trevordixon/zEqKy/
function cartesianCall(func, args) {
var combos = allCombos.apply(this, args);
for (var i = 0; i < combos.length; i++) {
func.apply(null, combos[i]);
}
}
function allCombos(first) {
var isArray = toString.call(first) === "[object Array]";
if (!isArray) first = [first]; // Convert non-array to an array with the value
// as the only element
else if (first.length === 0) first = [undefined]; // Convert empty array to an
// array with undefined as
// the only element
if (arguments.length === 1) return first; // base case for recursion
var result = [],
rest = allCombos.apply(this, Array.prototype.slice.call(arguments, 1));
for (var i = 0; i < first.length; i++) {
for (var j = 0; j < rest.length; j++) {
result.push([first[i]].concat(rest[j]));
}
}
return result;
}
Then use it like this:
function printArgs() { console.log('Called with arguments:', arguments); }
cartesianCall(printArgs, [
[true, false],
undefined,
[1, 2],
[],
'a string',
['a', 'b', 'c']
]);
Prints:
Called with arguments: [true, undefined, 1, undefined, "a string", "a"]
Called with arguments: [true, undefined, 1, undefined, "a string", "b"]
Called with arguments: [true, undefined, 1, undefined, "a string", "c"]
Called with arguments: [true, undefined, 2, undefined, "a string", "a"]
Called with arguments: [true, undefined, 2, undefined, "a string", "b"]
Called with arguments: [true, undefined, 2, undefined, "a string", "c"]
Called with arguments: [false, undefined, 1, undefined, "a string", "a"]
Called with arguments: [false, undefined, 1, undefined, "a string", "b"]
Called with arguments: [false, undefined, 1, undefined, "a string", "c"]
Called with arguments: [false, undefined, 2, undefined, "a string", "a"]
Called with arguments: [false, undefined, 2, undefined, "a string", "b"]
Called with arguments: [false, undefined, 2, undefined, "a string", "c"]
Notice that empty arrays are treated the same as undefined
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With