斯卡拉,通用转换函数的所有对象(scala, general purpose transform f

2019-10-18 08:16发布

我想有一些如下:

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是假的全部名单。

我们可以做如下:

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库实现的地方吗?

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


文章来源: scala, general purpose transform function for all objects
标签: scala