我想要有如下内容:
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));
也就是说,我只想在isNice
时应用onlyNice==true
过滤器。
我可以这样做:
val result = users
.filter(_.contains("john")
.map(._toUpperCase)
.filter(p => !onlyNice || isNice)
.map(p => countryOf(p));
但这会降低性能,因为即使onlyNice为false,我们也会遍历所有列表。
我们可以这样做:
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库中实现了吗?
答案 0 :(得分: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)