4

从我第一次读到:

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,_)))
)

我担心filter, flatMap&返回的不必要的中间集合map。第一个是通过添加withFilter方法在 Scala 2.8(?) 中修复的,我怀疑有一些魔术会根据使用情况改变这些方法的返回类型,因此当用作参数时,flatMap它们会返回非严格集合,但我找不到任何证据。我的怀疑是正确的,它并不像乍一看那样无效吗?

4

1 回答 1

5

这涉及到这个问题。具体来说,@IODEV的回答向您展示了如何查看脱糖形式:

$ 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))
    )
  )

我看不到任何可以保存的浪费中间集合,除非您使用可变构建器和while/或foreach调用来填充该构建器:

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 ... {}仅在您真正从中获得一些东西时才对构建器进行优化。

于 2013-05-26T21:32:26.313 回答