Convert one case class to another by using selected element

Viewed 114

Want to retrieve specific element from the input class while making the list of an output case class.

Example :

case class Student(id:Int, grade:Int, marks:Int)
case class StudentID(id:Int,grade:Int)


val inputList= Option[List(Student(1,100,234) ,Student(2,200,453), Student(3,300,556))]
val outputList=List(StudentID(1,100),StudentID(2,200),StudentID(3,300)) //result

I am trying to get only the id and grade. Please suggest. Also, the problem is input list is Option[].

val a = inputList.iterator.flatMap{ i=> outputList(i.map(_.id)) }
3 Answers

The question is still not clear, but I think this is the code you want:

inputList.map(_.map(s => StudentID(s.id, s.grade))).getOrElse(Nil)

The outer map and getOrElse(Nil) deal with the fact that the input is an Option[List] not just List. The inner map converts each element of the input List from Student to StudentID.

If the transition from Student-to-StudentID occurs at multiple places throughout the code base, then it might make sense to put the translation logic in the companion object.

case class Student(id:Int, grade:Int, marks:Int)
case class StudentID(id:Int,grade:Int)
object StudentID {
  def apply(s: Student) = new StudentID(s.id, s.grade)
}

val inputList= 
  Option(List(Student(1,100,234) ,Student(2,200,453), Student(3,300,556)))

inputList.map(_.map(StudentID(_)))
//res0: Option[List[StudentID]] =
//  Some(List(StudentID(1,100), StudentID(2,200), StudentID(3,300)))

I'd suggest that you use any of the many available case class mapping libraries.

Some examples:

You could also write your own solution with shapeless or macros, but it's not worth it since there are already working solutions.

Example with chimney:

import io.scalaland.chimney.dsl._

inputList match {
  case Some(l) => l.map(s => s.into[StudentID].transform)
  case None => Nil
}

Alternatively, you could just manually map one case class to another, but it can get tedious with case classes with many fields.

Related