Scala 将案例列表 class 转换为另一个案例列表 class
Scala converting List of case class to List of another case class
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))
您可以添加辅助构造函数。
case class student2(studentName:String, marks:Long) {
def this(s:student1) = this(s.name, s.marks)
}
. . .
val res: List[student2] = mylist.map(new student2(_))
或者您可以只进行模式匹配,但为此您确实应该将 class 名称大写。
val res: List[Student2] =
mylist.map{case Student1(n,m) => Student2(n,m)}
() 解决方案似乎是 Scala 2 (Scala 3) 中最简单的解决方案。以下使用库的解决方案更难但更灵活。
如果你有唯一的这样的转换,我会坚持你的方法或 @wvh 所建议的方法。
如果您有许多此类转换,请考虑使用其中一个数据处理库。
例如Chimney
import io.scalaland.chimney.dsl._
val res: List[student2] = mylist.map(
_.into[student2]
.withFieldRenamed(_.name, _.studentName)
.transform
)
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])
首先,请在CapitalCamelCase
中命名您的classes
。所以 Student1
和 Student2
.
现在,如果您有两个完全相同的 case classes
,就像在这种情况下,您可以在不使用任何库的情况下轻松地在它们之间进行转换。
val myList2: List[Student2] =
mylist.map(s => Student2.tupled(Student1.unapply(s).get))
这将适用于结构相似的任何两个 case classes
A
和 B
。
如果您使用的是 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))
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))
您可以添加辅助构造函数。
case class student2(studentName:String, marks:Long) {
def this(s:student1) = this(s.name, s.marks)
}
. . .
val res: List[student2] = mylist.map(new student2(_))
或者您可以只进行模式匹配,但为此您确实应该将 class 名称大写。
val res: List[Student2] =
mylist.map{case Student1(n,m) => Student2(n,m)}
如果你有唯一的这样的转换,我会坚持你的方法或 @wvh 所建议的方法。
如果您有许多此类转换,请考虑使用其中一个数据处理库。
例如Chimney
import io.scalaland.chimney.dsl._
val res: List[student2] = mylist.map(
_.into[student2]
.withFieldRenamed(_.name, _.studentName)
.transform
)
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])
首先,请在CapitalCamelCase
中命名您的classes
。所以 Student1
和 Student2
.
现在,如果您有两个完全相同的 case classes
,就像在这种情况下,您可以在不使用任何库的情况下轻松地在它们之间进行转换。
val myList2: List[Student2] =
mylist.map(s => Student2.tupled(Student1.unapply(s).get))
这将适用于结构相似的任何两个 case classes
A
和 B
。
如果您使用的是 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))