2016-06-20 7 views
0

私はScalaでいくつかのWebスクレイピングを試みており、現在はJSoupを使用しています。今度はイテレータがScalaで動作していないことがわかりましたので、私はちょっとしたことをして、イテレータを自分で書きました。それは次のようになります。pimpingの後でScalaが型を認識しないJSoup

object Pimp { 

    implicit class PimpElements(es: Elements) extends Iterable[Element] { 
    def iterator = new Iterator[Element] { 
     var currentElem = 0 

     def hasNext = currentElem < size 

     def next(): Element = { 
     currentElem += 1 
     es.get(currentElem - 1) 
     } 
    } 
    } 
} 

さて、IntelliJのか、Scalaは認識されないため、動作しないコード私のタイプElementであることがcider変数私が推測:

for (cider <- ciders; if cider.getElementsByClass("info").text() != "") { 
     ciderArray += Drink(DrinkType.CIDER, cider) 
} 

しかし、なぜありませんか?私next()方法はおそらくElementでなければなりませんes.get(i)を返し、以下のコードで動作します

for (i <- 0 to ciders.size() - 1; if ciders.get(i).getElementsByClass("info").text() != "") { 
     ciderArray += Drink(DrinkType.CIDER, ciders.get(i)) 
} 

は、基本的にはイテレータとして同じことをやって、このコードではありませんが、何らかの理由で認められますか? ciderのタイプは、intelliJによると、Anyであり、ではありません。

+1

sbtを使用してコンパイルしますか? IntelliJは、タイプを特定できないときにエラーを誤ってマークすることがあります。 – Ren

+0

まだ正常にコンパイルされませんか? Scala、Java、JSoupのどのバージョン?とアイデア?私は今IDEを試すことはできません。 –

答えて

0

forは、c.withFilter(p).foreach(f)に翻訳されています。

iteratorを呼び出す可能性があります。

この質問は、これらのエンコーディングがより推測された型パラメータまたはその他の影響をもたらす可能性があるため、興味深いものです。

ElementsArrayListです。

TraversableLike.withFilterIterator.withFilterとは異なります。

あなたの例は、size(どちらがstackoverflows)への呼び出しを修正した後に動作します。これは、要素と要素のJava型でも機能します。

object Test extends App { 

    case class Element(value: String) 

    type Elements = java.util.ArrayList[Element] 

    implicit class PimpElements(es: Elements) extends Iterable[Element] { 
    def iterator = new Iterator[Element] { 
     var currentElem = 0 

     def hasNext = currentElem < es.size 

     def next(): Element = { 
     currentElem += 1 
     es.get(currentElem - 1) 
     } 
    } 
    } 

    val vs = new java.util.ArrayList[Element] 
    vs.add(new Element("hi")) 
    vs.add(new Element("bye")) 

    for (v <- vs if v.value.startsWith("h")) println(v) 
} 

しかし、それはまた、このように動作します:

object Test extends App { 

    implicit class PimpElements(es: Elements) extends Iterator[Element] { 
    var currentElem = 0 

    def hasNext = currentElem < es.size 

    def next(): Element = { 
     currentElem += 1 
     es.get(currentElem - 1) 
    } 
    } 

    val vs = new Elements 
    vs.add(new Element("hi")) 
    vs.add(new Element("bye")) 

    for (v <- vs if v.value.startsWith("h")) println(v) 
} 

Traversableは、型推論の問題のために作るかもしれない型パラメータとしてその表現を追跡します。どちらのクラスもフィルタリングのためのラッパーを必要とします。しかし、Iteratorは、フィルタリング時にforeachをオーバーライドしないので、nextへのコールでは、フィルタリングされていない最後の要素がhasNextに保存されます。可能であれば、Traversable.foreachがより効率的です。

+0

私はScalaにはとても新しいので、あなたが何を意味するかは100%わかりません。 Scalaのforループが私の 'iterator'メソッドを呼び出さないと言っていますか?私は 'es.size'エラーを修正しましたが、以前よりもうまく動作するわけではありません:/ – Zorobay

+0

これは' foreach'を直接呼び出します。 「ifガード」は「withFilter」に変換されます。イテレータがどのように呼び出されるかは、(驚くべきことに) 'Iterable'または' Iterator'を供給する2つの例では異なります。 –

関連する問題