scala - 执行条件转换的惯用方法

标签 scala

我有一个对象x。我将对它进行一系列的改造。这可以很容易地表达为

x.transformA.transformB.transformC

但是,在每次转换之前,我还应该检查条件。仅当条件为真时我才应该执行转换。我有两种方式来表达这一点。第一个是将 x 定义为 var。

var x = anObject
if (x.condA) x = x.transformA
if (x.condB) x = x.transformB
if (x.condC) x = x.transformC
// final result in x

或者,为了避免 var,我定义了一系列中间变量

val x0 = anObject
val x1 = if (x0.condA) x0.transformA else x0
val x2 = if (x1.condB) x1.transformB else x1
val x3 = if (x2.condC) x2.transformC else x2
// final result in x3

这似乎相当麻烦,甚至在剪切和粘贴线条时容易出错。有更惯用的表达方式吗?

最佳答案

可以将一系列条件转换表达为函数的组合。这样每个转换都可以独立声明,并重用来构建新的转换。

举个例子:

val ta: MyClass => MyClass = {case x if x.condA => x.transformA
                              case x => x}
val tb: MyClass => MyClass = {case x if x.condB => x.transformB
                              case x => x}
val tc: MyClass => MyClass = {case x if x.condC => x.transformC
                              case x => x}

然后我们可以组合这些来形成我们的转换:

val transformation = ta andThen tb andThen tc
val transformedObj =  transformation(x)

我们可以从上面看到我们一遍又一遍地重复相同的模式。为了避免这种情况,我们可以创建一个函数来创建部分函数,​​从而减少样板代码:

def mkTf[T](cond: T => Boolean, transf: T => T): T => T = {
  case x if cond(x) => transf(x)
  case x => x
}

然后我们可以将我们的组合重写为:

val transformation = mkTf[MyClass](_.condA,_.transformA) andThen
                     mkTf[MyClass](_.condB,_.transformB) andThen
                     mkTf[MyClass](_.condC,_.transformC)

关于scala - 执行条件转换的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40595402/

相关文章:

scala - Scala缓存是否转换为功能接口(interface)

scala - 方法 flatMap 没有类型参数

Scala 错误 : type arguments do not conform to class type parameter bounds

scala - 使用 elastic4s 从原始 JSON 创建索引

scala - 如何用新值填充对象列表

scala - 无法在 Scala 中编写同时适用于 Double 和 Float 的方法

scala - 为什么 Scala 函数类型符合函数特征?

scala - 如何在 case 类中指定多个构造函数?

Scala/Spark 无法匹配函数

scala - 如何使用 Scala Breeze 对向量执行逐元素标量运算?