2013-07-30 4 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 аргументов)?

EDIT: так функция будет называться:

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'] 
]); 

Печать:

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

Обратите внимание, что пустые массивы обрабатываются так же, как undefined.

+0

Когда любой массив представляет собой пустой список, не переставляет, он должен иметь возможность перестановочить с нулевым значением – zsong

+0

Хорошая точка. Я думаю, что редактирование позаботится об этом случае. –

+0

Я считаю, что когда один из массивов пуст, функция не будет называться –

5

Declare вы действуете без параметров и использовать arguments ключевое слово:

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

Это лучший способ обойти все, просто будьте осторожны, чтобы не определять какие-либо вспомогательные функции внутри цикла. –

+2

Это не отвечает на вопрос. Ему все равно придется делать много неприятных циклов. –

+0

@TrevorDixon Мой ответ был опубликован до того, как вопрос с опцией был обновлен с дополнительной информацией. Таким образом, это ответ на вопрос: * Возможно ли, что функция записи позволяет мне это, поэтому я могу назвать ее следующим: cartesianCall (array1, array2, array3, myFunc); * –

Смежные вопросы