0

フラットな引数に対して機能する関数がある場合があります。例えば:

send(player,message)

しかし、代わりにプレイヤー/メッセージのコレクションがある場合はどうなるでしょうか?

message = ['Welcome!','Check our site for events.']
players = [Player1,Player2,Player3]

for ループを記述すると可読性が低下し、引数がコレクションであるかオブジェクトであるかが静的にわからない場合は機能しません。関数を書き直すことは、実行可能でないか、面倒で、コードの重複を助長する場合があります。より簡単な解決策は何ですか?

4

1 に答える 1

0

関数を独自の引数のデカルト積を取り、元の関数を呼び出す関数に変換するデコレータを作成できます。

function send(player,message) {
    console.log('To ',player,': ',message);
}
cartesian(send)(['Player1','Player2','Player3'],['Welcome!','Check our site.']);
//Output:
//To Player1 : Welcome!
//To Player1 : Check our site.
//To Player2 : Welcome!
//To Player2 : Check our site.
//To Player3 : Welcome!
//To Player3 : Check our site.

これは Javascriptでデコレータ (" cartesian ") を実装します:

function cartesian_product(arr){
    //cartesian_product( [[1,2],[3,4]] ) = [[1,3],[1,3],[2,3],[2,4]]

    function partial_product(arr,i){
        //partial_product([[1,2],3],0) = [[1,3],[2,3]]
        var result = []
        for (j=0; j<arr[i].length; ++j){
            arr_changed = arr.slice();
            arr_changed.splice(i,1,arr[i][j]);
            result.push(arr_changed);
        };
        return result;
    };

    var result = [arr.slice()];
    for (var x=0; x<arr.length; ++x){
        for (var y=0; y<result.length; ++y){
            if (result[y][x] instanceof Array) {
                result.splice.apply(result,[y,1].concat(partial_product(result[y],x)));
            }
        }
    }
    return result;
};

function cartesian(func){
    //cartesian(func)([1,2],[3,4]) = [func([1,3]),func([1,4]),func([2,3]),func([2,4])]
    _this = this;
    return function(){
        var args_list = cartesian_product(Array.prototype.slice.call(arguments));
        var return_values = []
        for (var i=0; i<args_list.length; ++i){
            return_values.push(func.apply(_this,args_list[i]))
        }
        return return_values;
    }
}
于 2012-05-08T18:50:54.713 に答える