5

次のように、Scalaのリストのリストがあります。

val inputList:List[List[Int]] = List(List(1, 2), List(3, 4, 5), List(1, 9))

すべてのサブリストの外積のリストが必要です。

val desiredOutput: List[List[Int]] = List( 
        List(1, 3, 1), List(1, 3, 9),
        List(1, 4, 1), List(1, 4, 9),
        List(1, 5, 1), List(1, 5, 9),
        List(2, 3, 1), List(2, 3, 9),
        List(2, 4, 1), List(2, 4, 9),
        List(2, 5, 1), List(2, 5, 9))

inputList とサブリストの要素数は固定されていません。これを行うScalaの方法は何ですか?

4

4 に答える 4

4

を使用する場合scalaz、これは次の場合に適している可能性がありますApplicative Builder

import scalaz._
import Scalaz._

def desiredOutput(input: List[List[Int]]) = 
  input.foldLeft(List(List.empty[Int]))((l, r) => (l |@| r)(_ :+ _))

desiredOutput(List(List(1, 2), List(3, 4, 5), List(1, 9)))

私自身は scalaz にあまり詳しくありませんが、これを行うにはもっと強力な魔法があると思います。

編集

Travis Brown が提案するように、次のように記述します。

def desiredOutput(input: List[List[Int]]) = input.sequence

そして、この質問の答えは、何が機能するかを理解するのに非常に役立ちますsequence

于 2012-11-26T16:04:13.637 に答える
4

これは、再帰を使用して機能する方法です。ただし、末尾再帰ではないため、スタックオーバーフローに注意してください。ただし、補助関数を使用して末尾再帰関数に変換できます。

def getProduct(input:List[List[Int]]):List[List[Int]] = input match{
  case Nil => Nil // just in case you input an empty list
  case head::Nil => head.map(_::Nil) 
  case head::tail => for(elem<- head; sub <- getProduct(tail)) yield elem::sub
}

テスト:

scala> getProduct(inputList)
res32: List[List[Int]] = List(List(1, 3, 1), List(1, 3, 9), List(1, 4, 1), List(1, 4, 9), List(1, 5, 1), List(1, 5, 9), List(2, 3, 1), List(2, 3, 9), List(2, 4, 1), List(2, 4, 9), List(2, 5, 1), List(2, 5, 9))
于 2012-11-26T15:28:35.557 に答える