惯用Scala懒惰地产生组合的方式

tux*_*dna 7 combinations scala

我想生成一些值的组合,如下面的代码所示:

object ContinueGenerate {

  val foods = List("A", "B", "C")
  val places = List("P1", "P2", "P3")
  val communities = List("C1", "C2", "C3", "C4")

  case class Combination(food: String, place: String, community: String)

  def allCombinations() = {
    for {
      food <- foods; place <- places; community <- communities
    } yield Combination(food, place, community)
  }

  def main(args: Array[String]) {
    allCombinations foreach println
  }

}
Run Code Online (Sandbox Code Playgroud)

然而,这种方法的问题在于,所有数据都是立即生成的.当尺寸大小时foods,这是一个大问题,places并且communities变得非常大.除了这三个之外,还可能有其他参数.

因此,我希望能够以连续样式生成组合,以便仅在请求时生成组合.

什么是惯用的Scala方式呢?

Rea*_*onk 7

你使用流:

object ContinueGenerate {

  val foods = Stream("A", "B", "C")
  val places = Stream("P1", "P2", "P3")
  val communities = Stream("C1", "C2", "C3", "C4")

  case class Combination(food: String, place: String, community: String)

  def allCombinations() = {
    for {
      food <- foods; place <- places; community <- communities
    } yield Combination(food, place, community)
  }

  def main(args: Array[String]) {
    allCombinations foreach println
  }

}
Run Code Online (Sandbox Code Playgroud)

A Stream缓存所有数据.如果您只想迭代一次,请使用Iterator,这应该是垃圾收集已遍历的元素.


mat*_*its 4

您可以通过使用View每个列表来完成此操作。在下面的代码中,我添加了一个副作用,因此当yield为每个元素调用时它是可见的。

val foods = List("A", "B", "C")
val places = List("P1", "P2", "P3")
val communities = List("C1", "C2", "C3", "C4")

case class Combination(food: String, place: String, community: String)

def allCombinations() =
  for {
    food <- foods; place <- places; community <- communities
  } yield {
    val comb = Combination(food, place, community)
    println(comb)
    comb
  }

//Prints all items
val combinations = allCombinations()

def allCombinationsView() =
  for {
    //Use a view of each list
    food <- foods.view; place <- places.view; community <- communities.view
  } yield {
    val comb = Combination(food, place, community)
    println(comb)
    comb
  }
//Prints nothing
val combinationsView = allCombinationsView()

//Prints 5 items
val five = combinationsView.take(5).toList
Run Code Online (Sandbox Code Playgroud)