Home > database >  Scala converting List of case class to List of another case class
Scala converting List of case class to List of another case class

Time:10-08

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

Also look at Monocle or Quicklens.

  • Related