2011-11-06 10 views
8

私は「Programming in Scala 2ed」を読んでいます。 24.4節では、Iterableにはイテレータなしで効率的に記述できない多くのメソッドが含まれていることに注意してください。表24.2にこれらのメソッドを示します。しかし、イテレータで効率的に実装できない理由がわかりません。たとえば、zipWithIndexを考えてみましょう。zipWithIndexがIterableで実装されていて、Traversableでないのはなぜですか?

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 
    } 

なぜこの定義をトラバーサブルに移動しないのですか?コードはまったく同じであり、効率的には違いがないと私には思われます。このメソッドは、単に内の各要素に対してfを呼び出す必要があるので

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

+0

ちょうど 'Traversableの上の' zipWithIndex'のためのユースケースを追加したいです'。トラバーサブルからランダム要素を選択するメソッドを実装している場合はどうなりますか?要素を反復処理するとき、索引が構造を持つ永続的な場所に対応していなくても、確率を助ける索引が必要です。 – schmmd

答えて

11

あなたは完全であり、実装はうまくいくはずです。 zipWithIndexIterableで定義されていて、Traversableではない正当な理由はありません。どちらも、トラバースの下での要素の順序付けについて何も保証しません。

は(これはStackOverflowの上の私の最初の答えです。私が参考にしてきたと思います。:)私はいませんでした場合は、教えてください。)

+0

本当に助かりました、あなたはそれを+6持っています!章のメソッドがIterableで実装されていることを明確に述べているので、私は何かが欠落していないことを確認していました。 – schmmd

10

Traversableは、要素が訪れ、唯一の次のシグネチャでのforeachメソッドを定義する必要がありますされる順序を保証するものではありません。任意の順序では、要素のインデックスを持つことは意味がありません。なぜなら、呼び出しごとに順序が異なる可能性があるからです(foreach)。

編集:これは本当に単なる説明で、なぜトラバーサブルではないのですか。 Luigiがコメントで指摘したように、zipWithIndexはSeqでより意味をなさないでしょう。

+1

私は、トラバーサブルでインデックスが意味を持たないことに同意します(グラフなど)。特に、コレクション*で取得したインデックス*で何もできません。しかし、他の何かのための "ループ"インデックスを持つことができます(そして、典型的なJavaスタイルの 'for'ループで' i'をまねることだけです)。なぜそうではありませんか? – Raphael

+1

'Iterable'(マップとセットを含む)は、要素が訪問される順序を保証しません。より良い質問は、 'zipWithIndex'が' Seq'ではなく 'Iterable'でなぜ定義されているのかを尋ねるでしょう。 –

+0

この議論の後、foreachはTraversable(なぜではない)かSeq(guarenteed order)のどちらかでより意味をなさないようです! – schmmd

関連する問題