Mam funkcję, która oblicza produkt liczb w tablicy. Funkcja powinna działać w ten sposób

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

W schemacie odbywa się to z kontynuacją, przechowywanie poprzedniego stanu funkcji (stan funkcji jest przechwycony tuż przed jego punktem wyjścia) Zobacz to

Więc w skrócie, chcę, aby funkcja JavaScript zwraca różne wartości w różnych czasach, z tym samym parametrem minął za każdym razem.

JavaScript jest dobrze zaprojektowanym językiem, więc mam nadzieję, że musi być coś, co można było naśladować. Jeśli zdarza się, że nie ma nic w JS, aby to zrobić, nie mam nic przeciwko zakończyć z porażką i kontynuować. Więc nie możesz powiedzieć, że jest to niemożliwe.

Dzięki.

4
riship89 11 grudzień 2011, 10:30

4 odpowiedzi

Najlepsza odpowiedź

JavaScript nie jest w stanie wspierać kontynuacji: brakuje jej połączeń ogona.

Ogólnie rzecz biorąc, napisałbym to, aby użyć "kolejki" rodzajów, chociaż CPS jest również zdolny (tylko mieć skończone stos :-) Należy również pamiętać, że inne państwo można również przechwycić w zamknięciu, dzięki czemu "wyraźna kontynuacja" Sortuje ... w bardzo brutto.

Przykład za pomocą zamknięcia i kolejki:

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]

Miłego kodowania.


"Zakończono wdrożenie". Chociaż ten szczególny problem może uniknąć mutacji tablicy i wystarczy użyć indeksu: obowiązują te same koncepcje. (Cóż, nieco inny

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
2
11 grudzień 2011, 07:39

Możesz podać funkcję właściwość, która zostanie zapamiętana między połączeniami:

function prod (array){
   if (typeof prod.index === "undefined" || prod.currentArray != array) {
      prod.currentArray = array;
      prod.index = 0;
   }

   if (prod.index >= array.length)
      return 0;

   //compute and return product
   var p = 1,
       c;
   while (prod.index < array.length) {
      c = array[prod.index++];
      if (c === 0)
         return p;
      p *= c;
   }
   return p;
}

Po prostu zgaduję z twojego opisu tego, co należy zwrócić, że na indywidualnym wezwanie do funkcji należy przyjmować produkt wszystkich numerów, ale nie zawierających następnego zera lub końca tablicy. Połączenia po zakończeniu tablicy powinny powrócić 0? Mogę w tym mylić algorytmę, ale masz pomysł na to, co sugeruję, aby pamiętać o stanie funkcji między połączeniami.

Dodałem nieruchomość do zapamiętania aktualnej tablicy. Tak długo, jak przechodzisz taką samą tablicę do funkcji, będzie kontynuowany z następnymi elementami, ale jeśli zdasz inną tablicę, zresetuje ...

2
nnnnnn 11 grudzień 2011, 07:13

Możesz spróbować czegoś takiego

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

Spowoduje to aktualizację globalnego wskaźnika zmiennego za każdym razem, gdy wywoływana jest funkcja.

1
dku.rajkumar 11 grudzień 2011, 06:51

To, czego szukasz tutaj są Generatory. Od 1,7, JavaScript obsługuje je.

1
John Clements 14 grudzień 2011, 01:33