1

我想要以下内容:

val onlyNice = true;

val users: List[String] = getNames()
val result = users
  .filter(_.contains("john")
  .map(._toUpperCase)
  .filter(p => isNice)   // here i would need to apply this filter only if `onlyNice` is true
  .map(p => countryOf(p));

也就是说,我只想isNiceonlyNice==true. 我可以这样做:

val result = users
  .filter(_.contains("john")
  .map(._toUpperCase)
  .filter(p => !onlyNice || isNice)
  .map(p => countryOf(p));

但这会降低性能,因为即使 onlyNice 为假,我们也会遍历所有列表。

我们可以这样做:

val tmp = users
  .filter(_.contains("john")
  .map(._toUpperCase)

val tmp2 = if (onlyNice) tmp.filter(isNice) else tmp

val result = tmp2.
  .map(p => countryOf(p));

但这更难阅读。

这对我来说似乎是一个很好的通用解决方案:

implicit class ObjectHelper[A](o: A) {
  def transform[B](f: A => B): B = f(o)
}

val result = users
  .filter(_.contains("john")
  .map(._toUpperCase)
  .transform(list => if (onlyNice) list.filter(isNice) else list)
  .map(p => countryOf(p));

你怎么看?

这个transform函数是否已经在某个地方的标准 scala 库中实现了?

4

1 回答 1

1

transform本质上是一种翻转形式的函数应用程序。

我不知道标准库中的实现,但它在 Scalaz 库中作为|>运算符实现,例如

import scalaz.syntax.id._

users |> (list => if (onlyNice) list.filter(isNice) else list)

请注意,因为在这种情况下,函数是类型A => A而不是A => B(即它是List[String] => List[String]),所以您可以等效地使用该identity函数,例如

users |> (if (onlyNice) (_.filter(isNice)) else identity)
于 2013-07-03T14:21:41.130 回答