【问题标题】:Scala converting List of case class to List of another case classScala将案例类列表转换为另一个案例类列表
【发布时间】:2021-10-08 07:16:35
【问题描述】:
case class student1(name :String, marks :Long)
 
case class student2(studentName:String, marks:Long)
 
val mylist:List[student1] = List( student1("a",100) , student1("b",200))

如何以比这更优雅的方式将mylist 转换为List[student2]

val res: List[student2] = mylist.map(s => student2(s.name,s.marks))

【问题讨论】:

  • 您的解决方案有什么问题或“不优雅”(无论这意味着什么)?

标签: scala case-class


【解决方案1】:

你可以添加一个辅助构造函数。

case class student2(studentName:String, marks:Long) {
  def this(s:student1) = this(s.name, s.marks)
}

. . .

val res: List[student2] = mylist.map(new student2(_))

或者你可以只做一个模式匹配,但是你真的应该把你的类名大写。

val res: List[Student2] =
  mylist.map{case Student1(n,m) => Student2(n,m)}

【讨论】:

    【解决方案2】:

    首先,请将您的classes 命名为CapitalCamelCase。所以Student1Student2

    现在,如果您有两个完全相同的case classes,就像在这种情况下,您可以轻松地在它们之间进行转换,而无需使用任何库。

    val myList2: List[Student2] = 
      mylist.map(s => Student2.tupled(Student1.unapply(s).get))
    

    这适用于结构相似的任意两个case classes AB

    【讨论】:

    • 不错。点赞。
    【解决方案3】:

    @sarveshseri's (@esse's) 解决方案似乎是 Scala 2 (Scala 3) 中最简单的一种。以下使用库的解决方案更难但更灵活。


    如果您只有这样的转变,我会坚持您的方法或 @wvh 建议的方法。

    如果您有许多此类转换,请考虑使用其中一个数据操作库。

    例如Chimney

    import io.scalaland.chimney.dsl._
    
    val res: List[student2] = mylist.map(
      _.into[student2]
       .withFieldRenamed(_.name, _.studentName)
       .transform
    )
    

    Shapeless

    import shapeless.{Generic, HList}
    
    trait Convert[A, B] {
      def apply(a: A): B
    }
    object Convert {
      implicit def mkConvert[A <: Product, B <: Product, L <: HList](implicit
        genericA: Generic.Aux[A, L],
        genericB: Generic.Aux[B, L]
      ): Convert[A, B] = a => genericB.from(genericA.to(a))
    }
    
    implicit class ConvertOps[A](val a: A) extends AnyVal {
      def to[B](implicit convert: Convert[A, B]): B = convert(a)
    }
    
    val res: List[student2] = mylist.map(_.to[student2])
    

    另请查看MonocleQuicklens

    【讨论】:

      【解决方案4】:

      如果您使用的是 Scala 3(又名 dotty),则以下代码有效:

      scala> import scala.deriving.Mirror
                                                                                                                                                                                 
      scala> mylist.map(summon[Mirror.Of[student2]].fromProduct)
      val res1: List[student2] = List(student2(a,100), student2(b,200))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 2016-07-27
        • 2014-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多