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))
How can I convert mylist
into List[student2]
in more elegant way than this?
val res: List[student2] = mylist.map(s => student2(s.name,s.marks))
CodePudding user response:
You could add an auxiliary constructor.
case class student2(studentName:String, marks:Long) {
def this(s:student1) = this(s.name, s.marks)
}
. . .
val res: List[student2] = mylist.map(new student2(_))
Or you could just do a pattern match, but for that you really should capitalize your class names.
val res: List[Student2] =
mylist.map{case Student1(n,m) => Student2(n,m)}
CodePudding user response:
First of all, please name your classes
in CapitalCamelCase
. So Student1
and Student2
.
Now, If you have two exactly same case classes
like in this case, you can easily convert between them without using any libraries.
val myList2: List[Student2] =
mylist.map(s => Student2.tupled(Student1.unapply(s).get))
This will work for any two case classes
A
and B
which are similar in strcuture.
CodePudding user response:
If you have the only such transormation I'd stay with your approach or with the one suggested by @wvh.
If you have many such transformations consider to use one of data manipulating libraries.
For example Chimney
import io.scalaland.chimney.dsl._
val res: List[student2] = mylist.map(
_.into[student2]
.withFieldRenamed(_.name, _.studentName)
.transform
)
or 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])