2016-06-21 12 views
1

私はせっかちのためにスカラを通り過ぎていて、理解できないと思われる複数の条件ループの例を見つけました。複数の条件を持つスカラループ - 何が返されますか?

Javaのバックグラウンドから来ている私はこれらのループをネストされたforループとして見ています。しかし、なぜ最初の返信はcollectionであり、2番目の返信はStringですか? desugarため

scala> for (i <- 0 to 1; c <- "Hello") yield (i + c).toChar 
res11: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p) 

scala> for (c <- "Hello"; i <- 0 to 1) yield (i + c).toChar 
res12: String = HIeflmlmop 
+0

を参照してください。http://docs.scala-lang.org/tutorials/FAQ/yield.html –

+0

要するに、for-comprehensionsでは、戻り値の型は最初のコレクションによって決まりますまたはトラバーサブル)を使用します。 –

答えて

4

は単なるシンタックスシュガーであり、は、mapflatMapwithFilter(また、利回りを使用しない場合はforeach)の呼び出しに変換されます。

for { 
    i <- 0 to 1 
    c <- "Hello" 
} yield (i + c).toChar 

RangeVector内となり、ここで例えば、彼らは上と呼ばれる、または最も近いされたコレクションの同じ型を返すという方法で定義されている

(0 to 1).flatMap(i => "Hello".map(c => (i + c).toChar)) 

これらの変圧器と等価です任意の文字を含むRangeを持つことはできません。 Stringから始まって、まだStringに戻ることができます。

一般に、このように考えることができます。理解のために作成された結果のタイプは、最初のジェネレータのタイプと同じになります。例えば

あなたはSet

for { 
    c <- "Hello".toSet[Char] 
    i <- 0 to 1 
} yield (i + c).toChar 

に文字列を変換する場合は、Setを取り戻すだろう、それが設定されているので、結果が異なっているので、それは重複を含まれません。 Set(e, f, m, I, l, p, H, o)

どのようにタイプが決定されるかは、CanBuildFrom形質を伴う。あなたはそれがどのように動作するかについてもっと読むことができますhere

+0

あなたの例を 'Set'で行う別の方法は次のとおりです:for {_ < - Set( ''); c < - "こんにちは"; i < - 0から1}は(i + c).Char'を出力する。それがより良い方法であるとは確信していませんが、時にはきれいに見えます。 –

1

使用のScala 2.11.8 REPL(印刷後の記者]タブ、<pressed TAB here>を削除):

scala> for (i <- 0 to 1; c <- "Hello") yield (i + c).toChar //print<pressed TAB here> 

scala.Predef.intWrapper(0).to(1).flatMap[Char, scala.collection.immutable.IndexedSeq[Char]](((i: Int) => 
    scala.Predef.augmentString(scala.Predef.augmentString("Hello"). 
     map[Char, String](((c: Char) => i.+(c).toChar))(scala.Predef.StringCanBuildFrom))))(scala.collection.immutable.IndexedSeq.canBuildFrom[Char]) // : scala.collection.immutable.IndexedSeq[Char] 

scala> for (i <- 0 to 1; c <- "Hello") yield (i + c).toChar //print 
res4: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p) 

scala> for (c <- "Hello"; i <- 0 to 1) yield (i + c).toChar //print<pressed TAB here> 

scala.Predef.augmentString("Hello").flatMap[Char, String](((c: Char) => scala.Predef.intWrapper(0).to(1). 
     map[Char, scala.collection.immutable.IndexedSeq[Char]](((i: Int) => i.+(c).toChar))(scala.collection.immutable.IndexedSeq.canBuildFrom[Char])))(scala.Predef.StringCanBuildFrom) // : String 

scala> for (c <- "Hello"; i <- 0 to 1) yield (i + c).toChar //print 
res5: String = HIeflmlmop 

より読みやすい出力:内包表記について

scala> (0 to 1).flatMap(i => "Hello".map(c => (i+c).toChar)) 
res14: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p) 

scala> "Hello".flatMap(c => (0 to 1).map(i => (i + c).toChar)) 
res15: String = HIeflmlmop 
関連する問題