2017-12-08 7 views
0

私はScalaには比較的新しいので、私は言語に自信がないし、問題を解決するためにあなたの助けが必要です。 for-comprehensionは、複雑なmap/flatMap階層を単純化するための文法的な砂糖に過ぎないことを私は知っています。理解のための動的

ここで、3つの異なる範囲間隔を考えてみましょう。これは、値の可能な組み合わせ(間隔を尊重)をすべて作成するために組み合わせる必要があります。

:としてScalaのコンパイラによって変換され

val intervalX = 1 to 5 
val intervalY = 6 to 13 
val intervalZ = 20 to 50 
for { 
    x <- intervalX; 
    y <- intervalY; 
    z <- intervalZ 
} yield (x,y,z) 

使用して問題を解決することができるため、理解

intervalX.flatMap{x => 
    intervalY.flatMap{y => 
     intervalZ.map{z => (x,y,z)} 
    } 
} 

しかし、入力がの変数の間隔dで与えられると問題はより困難になります。可能なすべてのd-タプルを取得して、同じ操作を実行することは可能ですか? foldLeft操作で解決できると思いますが、現時点で正しく書き込めません。手伝って頂けますか?

おかげ

+1

定型のたくさんのことが可能ですが、私はお勧めします可能な限り定型文を減らすのに役立つライブラリを使用すると、私はシェイプレスが理想的だと思います。 (タプルは22までサポートされているので、 'd'は' <= 22'でなければなりません。) –

+0

ありがとう。私はこのライブラリを知らない。私はどの機能について勉強すべきかというヒントを教えてもらえますか? – Luca

+1

入力が 'Range'sの' HList'である場合、その結果はその組み合わせの 'HList'になります。また、['shapeless.syntax.std.tuple'](https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#hlist-style-operations-on-standard-scalaタプル)の部分があなたの期待にさらに近づくかもしれません。 –

答えて

2

あなたが結果としてタプルせずに生きることができる場合は、組み合わせを表すfoldLeftを使用してバージョンと返すリストは次のようになります。

val intervalX = 1 to 5 
val intervalY = 6 to 13 
val intervalZ = 20 to 50 
val ranges = intervalZ :: intervalY :: intervalX :: Nil 
val combos = ranges.foldLeft(Iterable[Seq[Int]](Nil)) { case (c, e) => 
    for { 
     i <- e 
     j <- c 
    } yield i +: j 
} 
combos foreach { println(_) } 
関連する問題