Scala用于理解和flatMap / map中间结果

时间:2013-05-26 19:57:05

标签: scala for-comprehension

从我第一次读到:

for {
  harpo<-list1 if harpo.length>0
  groucho<-list2
  chico<-list3
} yield (harpo, groucho, chico)

转换为:

list1.filter(_.length>0).flatMap(harpo =>      
      list2.flatMap(groucho=>list3.map((harpo,groucho,_)))
)

我担心filterflatMap&amp;返回的不必要的中间集合。 map。第一个是通过添加withFilter方法在Scala 2.8(?)中修复的,我怀疑有一些魔法可以根据用途改变这些方法的返回类型,因此当用作{{{{ 1}}他们返回一个非严格的集合,但我找不到任何证据。我的怀疑是否正确,并不像第一眼看上去那样无效?

1 个答案:

答案 0 :(得分:4)

这与this question有关。具体而言,@ IODEV的the answer向您展示了如何查看这些表格:

$ scala -Xprint:typer -e
'val list1 = List("foo", "bar"); val list2 = list1; val list3 = list1;
for (harpo<-list1 if harpo.length>0; groucho <- list2; chico <- list3) 
yield (harpo, groucho, chico)'

(没有换行符)

list1.withFilter(_.length() > 0)
  .flatMap(harpo =>
    list2.flatMap(groucho =>
      list3.map(chico => (harpo, groucho, chico))
    )
  )

我没有看到您可以保存的任何浪费的中间集合,除非您选择可变构建器以及whileforeach调用来填充该构建器:

val b = List.newBuilder[(String, String, String)]
for(harpo <- list1 if harpo.length() > 0; groucho <- list2; chico <- list3) {
  b += ((harpo, groucho, chico))
}
b.result()

问题是,您的特定代码是否存在严重的性能问题。例如。你的藏品非常庞大。如果没有,请使用更具惯用的形式(for ... yield)。只有当您真正从中获得某些内容时,才会使用for ... {}优化构建器。