scala - 修剪案例类的字符串字段的值

标签 scala shapeless

我正在使用 shapeless 编写一个通用函数它采用 case class 的实例并修剪所有字符串字段的值。 case 类可以有可选字段、嵌套对象、列表等。

我有一个案例类 Person .

case class Person(name: Option[String], address: List[String], friends: List[Person])

我目前拥有的功能:
import shapeless._, ops.hlist._

  object trimmer extends Poly1 {
    implicit val stringOptCase = at[Option[String]](_.map(_.trim))
    implicit val stringListCase = at[List[String]](_.map(_.trim))
    implicit def skipCase[A] = at[A](identity)
  }

  def trimStringValues[A, R <: HList](a: A)(implicit
                                     gen: Generic.Aux[A, R],
                                     mapper: Mapper.Aux[trimmer.type, R, R]
  ) = gen.from(mapper(gen.to(a)))

当我使用上述功能时,它仅适用于根级别 name类领域Person .它不适用于列表或对象字段。
val person = Person(name = Some(" john "), address = List(" ny"," vegas "), friends = List(Person(Some(" alicia"), List(" peter"), Nil)))

trimStringValues(person) // Person(Some(john),List(ny, vegas),List(Person(Some( alicia),List( peter),List())))

我该如何解决这个问题?

最佳答案

首先,它似乎正在处理 address以及 name在您评论的输出中,这是意料之中的。它不适用于 friends因为 List[Person]匹配 skipCase案例—它既不是 Option[String]List[String] .

解决此问题的最简单方法是使用 Shapeless 的 everywhere组合器。鉴于您上面的代码,您可以编写以下内容:

scala> shapeless.everywhere(trimmer)(person)
res1: Person = Person(Some(john),List(ny, vegas),List(Person(Some(alicia),List(peter),List())))

事实上,您可以使用更简单的 trimmer 完成同样的事情。执行:
object trimStrings extends Poly1 {
  implicit val stringCase: Case.Aux[String, String] = at[String](_.trim)
}

或者等效但更简洁:
import shapeless.poly.->

object trimStrings extends (String -> String)(_.trim)

进而:
scala> shapeless.everywhere(trimStrings)(person)
res5: Person = Person(Some(john),List(ny, vegas),List(Person(Some(alicia),List(peter),List())))

如果您想更准确地控制修剪哪些字符串,您可以返回到您的原始实现并添加显式 List[Person]案例,或更通用的案例,将匹配这样的类型并应用 trimmer递归地。既然您说要修剪所有字符串,那么 everywhere听起来这就是你想要的。

关于scala - 修剪案例类的字符串字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54589438/

相关文章:

scala - 带有中缀符号的有趣行为

scala - Slick "==="仅编译用于理解

scala - 如何在 Scala 中表示案例类的部分更新?

list - Scala 函数中的异构参数

scala - 在scala 2.13中,为什么有时无法显式调用类型类?

scala - 具有自定义类型绑定(bind)的无形状映射和子类型多态性

scala - 使用 JavaMail + Scala 从 Gmail 检索邮件时出错

scala - 如何在 scala 中模拟 Unit 方法

scala - 从 native 矩阵格式转换,缩放

shapeless - 使用 productElements 元组到 HList