22

I have a tuple

val tuple = ("Mike", 40)

and a case class

case class Person(name: String, age: Int)

How can I pack my tuple to object of Person class? Are there any ways except this:

new Person(tuple._1, tuple._2)

Maybe somesing like

tuple.asInstanceOf[Person]

Thanks.

Pavel Varchenko
  • 727
  • 1
  • 11
  • 21

4 Answers4

42

tupled

You could convert Person.apply method to function and then use tupled method on function:

(Person.apply _) tupled tuple

In scala 2.11.8 and scala 2.12 companion object of case class extends FunctionN, so this would be enough:

Person tupled tuple

Pattern matching

An analogue of new Person(tuple._1, tuple._2) without ugly _N methods is the pattern matching:

tuple match { case (name, age) => Person(name, age) }
senia
  • 37,745
  • 4
  • 88
  • 129
  • I'd add this conversion as implicit function of `Person` – expert Dec 14 '15 at 22:55
  • `Person tupled tuple` is enough. I'm using Scala 2.11.8. – mixel Dec 06 '16 at 13:01
  • For some reason, this does not work for me in 2.12.12: `value tupled is not a member of object ...` It's a case class with companion object. – Markus Appel Mar 02 '21 at 10:30
  • @MarkusAppel `Person tupled tuple` works only if object `Person` extends `FunctionN`. See this answer: https://stackoverflow.com/a/25414109/406435 . This feature is dropped in scala 3: https://scalacenter.github.io/scala-3-migration-guide/docs/incompatibilities/other-changed-features.html#case-class-companion – senia Mar 03 '21 at 16:10
4

Little "just for fun" version, which can be abstracted further. Of course with a little help from shapeless:

  import shapeless._
  import Tuples._

  case class Person(name: String, age: Int)
  val tup = ("Alex", 23)

  val personIso = Iso.hlist(Person.apply _, Person.unapply _)

  personIso.from(tup.hlisted)
4lex1v
  • 21,367
  • 6
  • 52
  • 86
3

You could define an implicit that does the conversion. I use this in my parameterized tests to improve readability.

// Define adults with tuples
implicit def makePerson(in:(String,Int))=new Person(in._1,in._2);
// Define kids with triples
implicit def makeUnderagePerson(in:(String, Int, String))=new Person(in._1,in._2, new Person(in._3));

//create single person:
val person:Person=("Mike", 40)

//crate a list of persons:
//
//Remember to type the list, this is what forces the implicit on each tuple.
//                     ||
//                     \/
val personList=List[Person](
("Mike", 40),
("Jane", 41),
("Jack", 42),
// Uses the implicit ment for kids. 
("Benjamin", 5, Jack)
);

I love this lanuage.

Espen Brekke
  • 404
  • 3
  • 7
0

Scala 3 has first class support for the conversion between tuples and case classes:

scala> val tuple = ("Mike", 40)
val tuple: (String, Int) = (Mike,40)

scala> case class Person(name: String, age: Int)
// defined case class Person

scala> val person: Person = summon[deriving.Mirror.ProductOf[Person]].fromProduct(tuple)
val person: Person = Person(Mike,40)

scala> Tuple.fromProductTyped[Person](person)                                                                                                                                   
val res1: (String, Int) = (Mike,40)
Taig
  • 6,718
  • 4
  • 44
  • 65