2013-07-30 129 views
6

考虑以下数组:与所有可能的参数JS调用功能置换

var array1 = [true, false]; 
var array2 = [1, 2]; 
var array3 = ["a", "b", "c"]; 

我想打电话给我的功能myFunc(arg1, arg2, arg3)所有参数的组合。但我想避免“地狱”。

是否有可能写入功能,可以让我,这样我就可以把它有些像:

cartesianCall(array1, array2, array3, myFunc); 

理想与阵列(myFunc的参数)的变盘点?

编辑: 这样的功能将被称为:

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"); 
+0

你想把你的数组融合到一个吗? –

+0

我想在带有参数的“myFunc”中执行多个操作.. –

+0

而您想要避免嵌套的'for'循环? – tymeJV

回答

3

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; 
} 

然后使用它像这样:

function printArgs() { console.log('Called with arguments:', arguments); } 

cartesianCall(printArgs, [ 
    [true, false], 
    undefined, 
    [1, 2], 
    [], 
    'a string', 
    ['a', 'b', 'c'] 
]); 

打印:该空阵列也一样undefined

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"] 

的通知。

+0

当任何数组是一个空列表时,它不排列,它应该能够置换值为null – zsong

+0

好点。我认为编辑负责处理这种边缘情况。 –

+0

我的事情,当一个数组是空的,函数将不会被称为 –

5

声明你的功能不带参数,并使用arguments关键字:

function cartesianCall() { 
    for (var i = 0; i < arguments.length; i++) { 
    // do something with arguments[i] 
    } 
} 
+0

这是解决问题的最好方法,只是要小心,不要在循环中定义任何辅助函数。 –

+2

这并没有真正回答这个问题。他仍然需要在那里做很多讨厌的循环。 –

+0

@TrevorDixon我的回答是在OP问题已更新并附加信息之前发布的。所以这是这个问题的答案:*是否有可能编写函数,允许我这样做,所以我可以这样调用它:cartesianCall(array1,array2,array3,myFunc); * –