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])
