2011-11-06 22 views
8

"Scala 2ed'de Programlama" dersini okuyorum. 24.4 bölümünde, yineleyicinin, yineleyici olmadan verimli bir şekilde yazılamayan birçok yöntem içerdiği belirtilmektedir. Tablo 24.2 bu yöntemleri içerir. Ancak, bazılarının neden yineleyici üzerinde verimli bir şekilde uygulanamadığını anlamıyorum. Örneğin, zipWithIndex'i düşünün.zipWithIndex neden Yinelenebilir ve Geçilir değil?

def zipWithIndex[A1 >: A, That](implicit bf: CanBuildFrom[Repr, (A1, Int), That]): That = { 
    val b = bf(repr) 
    var i = 0 
    for (x <- this) { 
     b += ((x, i)) 
     i +=1 
    } 
    b.result 
    } 

Bu tanım neden hareket edebilir şekilde taşınmıyor? Bana öyle geliyor ki, kod tam olarak aynı olabilir ve verimli bir şekilde bir farklılık olmayacaktı.

+0

Sadece Traversable 'üzerinde zipWithIndex'' için bir kullanım durumunda eklemek istedim '. Bir çaprazlamadan rasgele bir öğe seçmek için bir yöntem uyguluyorsanız ne olur? Elemanların üzerinde yineleme yaparken, indeks yapıya sahip kalıcı bir yere karşılık gelmese de olasılıklara yardımcı olacak bir dizine ihtiyacınız vardır. – schmmd

cevap

11

Tamamen doğru ve uygulamanız çalışmalıdır. Iterable'da tanımlanan zipWithIndex numaralı ve Traversable numaralı telefon numaralarının olmaması için iyi bir sebep yok; traversal altındaki elemanların sıralanması konusunda herhangi bir garanti vermez.

(Bu StackOverflow. Hope İlk yanıtım ben yardımcı oldum. :) Ben, söyle lütfen değil ettiyseniz içindir.)

+0

Tamamen yararlı, bunun için +6 var! Ben sadece bir şey kaçırmıyorum emin değilim çünkü bölüm açıkça tabloda daha kolay veya daha verimli olduğu için tablodaki yöntemlerin uygulandığını belirtiyor. – schmmd

10

Traversable elemanları ziyaret edilecek sırayı garanti ve yalnızca aşağıdaki imzası ile bir foreach yöntemini tanımlamak gerektirir değildir: bu yöntem sadece her elemanda için f çağırmak gerekiyor yana

def foreach[U](f: Elem => U): Unit 

Herhangi bir sipariş, siparişin her biri için foreach numaralı çağrı için farklı olabileceğinden, öğelerde bir dizin olması mantıklı değildir.

Düzeltme: Bu gerçekten yalnızca bir açıklamadır, neden bu Traversable'da değil. Luigi yorumlarda belirttiği gibi, zipWithIndex Seq'da daha anlamlı olur.

+1

Endekslerin bir "Traversable" üzerinde anlamlı olmadığını kabul ediyorum (örnek grafikler için düşünün). Özellikle, koleksiyonda * elde edilen endeksle * hiçbir şey yapamazsınız. Ama başka bir şey için "döngü" indeksine sahip olmak isteyebilirsiniz (ve bu sadece 'i' tipik bir Java tarzı '' '' i 'ye sahip olmanın taklit edilmesi için), neden olmasın? – Raphael

+1

'Iterable' (haritalar ve kümeleri içerir) hangi öğelerin de ziyaret edileceği konusunda garanti vermez. Daha iyi bir soru, "zipWithIndex" in neden "Seq" yerine "Iterable" üzerinde tanımlandığını sorar. –

+0

Bu tartışmadan sonra, foreach'in Traversable (why not) veya Seq (guarenteed order) üzerinde daha mantıklı olduğu görülüyor! – schmmd