2014-06-15 1 views
1

TraversableOnce implémente foldLeft avec mutable var result.Implémentation de foldLeft dans Scala

def foldLeft[B](z: B)(op: (B, A) => B): B = { 
    var result = z 
    this foreach (x => result = op(result, x)) 
    result 
} 

Je comprends qu'il ne soit pas pratique de mettre en œuvre foldLeft récursive. Maintenant, je me demande s'il est possible de mettre en œuvre foldLeft sans variables mutables efficacement.

Cela peut-il être fait? Pourquoi si ça ne peut pas?

Répondre

5

Queue-récursion est votre ami:

def foldLeft[A, B](xs: Seq[A], z: B)(op: (B, A) => B): B = { 
    def f(xs: Seq[A], acc: B): B = xs match { 
    case Seq() => acc 
    case x +: xs => f(xs, op(acc, x)) 
    } 
    f(xs, z) 
} 

BTW, TraversableOnce n'implémente pas head ou tail, la seule façon d'accéder aux éléments est d'utiliser foreach.

0
def foldLeft[B](z: B)(op: (B, A) => B): B = { 
    val thislist = this.toList 
    @tailrec 
    def myFold(result: B, list: List[A]): B = list match { 
    case Nil => result 
    case head :: tail => myFold(op(result,head), tail) 
    } 
    myFold(z, thislist) 
} 
+0

À moins que la collection soit une liste, l'opération 'toList' prend' O (n) '. C'est donc une solution inefficace. –

+0

Donc, foldLeft sera toujours O (n): p Comme sschaef dit, dans 'TraversableOnce' la seule façon d'accéder aux éléments est' foreach', donc quand vous voulez vraiment le faire récursivement, vous devrez perdre _some_ efficacité ... –

+0

Donc la réponse complète à cette question est: il est possible d'implémenter 'foldLeft' sans variables mutables de la façon la plus efficace, mais pas dans' TraversableOnce', en raison de l'absence de 'O (1)' head et les fonctions de la queue. –

Questions connexes