2011-12-11 4 views
4

私は、配列の数値の積を計算する関数を持っています。関数方式では、このJavaScriptのエミュレート/継続を使用しますか?

function prod (array){ 
//compute and return product 
} 

var arr = [1,2,3,0,4,5,0,6,7,8,0,9]; 

the function call: 
prod(arr); //should return 6 
prod(arr); //should return 20 
prod(arr); //should return 336 (6*7*8) 
prod(arr); //should return 9 
prod(arr); //should return 0 
prod(arr); //should return 0 
prod(arr); //should return 0 

ように動作する必要があり、これがで、see this

だから関数の前の状態を記憶する(ちょうどその出口ポイントの前に捕捉される機能の状態)で、継続して行われ短い、私はjavascript関数は、毎回同じパラメータで渡される異なる時間に異なる値を返します。

JavaScriptはうまく設計された言語ですので、これをエミュレートできるものが必要であることを願っています。 JSの中に何も起こらなければ何も起こらなければ、私は失敗と結論して進んでも構わない。だから、それは不可能だと自由に感じてください。

ありがとうございました。

+2

状態の静的変数keepmtrackがありませんでしたか? – SuitedSloth

+0

これらの数値の積は、ゼロをすべて取り除くまで0になります。 –

+1

明確ではありません - これらの値はどのように返されますか? –

答えて

3

JavaScriptは継続をサポートできません。テールコールはありません。

一般的に、私はCPSもできる(有限のスタックを持っています:-)しかし、ソートの "キュー"を使用するためにこれを書いています。他の状態もクロージャーでキャプチャすることができ、一種の「明白な継続」を意味します。クロージャとキューを使用して

例:

function prodFactory (array){ 
    // dupe array first if needed, is mutated below. 
    // function parameters are always locally scoped. 
    array.unshift(undefined) // so array.shift can be at start 
    // also, perhaps more closured state 
    var otherState 
    // just return the real function, yippee! 
    return function prod() { 
     array.shift() 
     // do stuff ... e.g. loop array.shift() and multiply 
     // set otherState ... eat an apple or a cookie 
     return stuff 
    } 
} 

var prod = prodFactory([1,2,3,0,4,5,0,6,7,8,0,9]) 

     // array at "do stuff", at least until "do stuff" does more stuff 
prod() // [1,2,3,0,4,5,0,6,7,8,0,9] 
prod() // [2,3,0,4,5,0,6,7,8,0,9] 
prod() // [3,0,4,5,0,6,7,8,0,9] 

ハッピーコーディング。


「完成した実装」。この特定の問題は配列の変異を避け、単にインデックスを使用することができますが、同じ概念が適用されます。 (まあ、少し異なるこのアプローチでオブジェクトが変異しているのに対し、単にインデックスで変数の上に閉じられたが、変更されるだろう。。)

function prodFactory (array) { 
    array = array.slice(0) 
    return function prod() { 
     var p = 1 
     for (var n = array.shift(); n; n = array.shift()) { 
     p *= n 
     } 
     return p 
    } 
} 

var prod = prodFactory([1,2,3,0,4,5,0,6,7,8,0,9]) 

prod() // 6 
prod() // 20 
prod() // 336 
+1

ソリューションは私によく見えます。サイドノート:テールコールは、継続を続けるためには必要ありません。私が最後にチェックしたとき、Rhinoは継続的な機能をサポートしていました。 –

+0

@JohnClements本当に、私は[JavaScript]言語レベルで他の形式のスタック操作は想定していませんでした;-)興味深いことに、JSエンジンが実装されたことはわかりませんでした。 –

2

あなたが呼び出しの間に記憶されますプロパティを機能を与えることができます。

私はちょうど、関数の個々の呼び出しで、次のゼロまでのすべての数値の積をとりますアレイ。配列の終了後の呼び出しは0を返しますか?私はアルゴリズムが間違っているかもしれませんが、コール間の関数の状態を覚えておくことを提案しています。

処理中の現在の配列を記憶するためのプロパティを追加しました。限り、あなたはそれが次の要素を継続しますが、別の配列を渡す場合、それはリセットされます関数の中に同じ配列を渡す保つよう...

1

あなたは

var index = 0; 
function prod (array){ 
    if(index < array.length){ 
    var prod=1; 
    for(int i=index;i<array.length;i++){ 
     if(array[i] != 0){ 
      prod = prod * array[i]; 
     } 
     else{ 
      index = i+1; 
      return prod; 
     } 
    } 
} 
return 0; 
} 

ような何かを試すことができますこれは、関数が呼び出されるたびにグローバル変数インデックスを更新します。

関連する問題