89

I frequently find myself working with Lists, Seqs, and Iterators of Tuples and would like to do something like the following,

val arrayOfTuples = List((1, "Two"), (3, "Four"))
arrayOfTuples.map { (e1: Int, e2: String) => e1.toString + e2 }

However, the compiler never seems to agree with this syntax. Instead, I end up writing,

arrayOfTuples.map { 
    t => 
    val e1 = t._1
    val e2 = t._2
    e1.toString + e2 
}

Which is just silly. How can I get around this?

user unknown
  • 35,537
  • 11
  • 75
  • 121
duckworthd
  • 14,679
  • 16
  • 53
  • 68

6 Answers6

151

A work around is to use case :

arrayOfTuples map {case (e1: Int, e2: String) => e1.toString + e2}
Nicolas
  • 24,509
  • 5
  • 60
  • 66
  • 40
    And you don't even need to type the tuple elements. case (e1, e2) => is good enough, the types of the tuple elements are known. – Didier Dupont Aug 01 '11 at 22:56
33

I like the tupled function; it's both convenient and not least, type safe:

import Function.tupled
arrayOfTuples map tupled { (e1, e2) => e1.toString + e2 }
thoredge
  • 12,237
  • 1
  • 40
  • 55
18

Why don't you use

arrayOfTuples.map {t => t._1.toString + t._2 }

If you need the parameters multiple time, or different order, or in a nested structure, where _ doesn't work,

arrayOfTuples map {case (i, s) => i.toString + s} 

seems to be a short, but readable form.

user unknown
  • 35,537
  • 11
  • 75
  • 121
  • 1
    I guess the main reason is that most of the time, the processing of the map function is far more complicated than `_.toString + _` and he wants to manipulate more comprehensible names than `t._1` and `t._2`. – Nicolas Aug 02 '11 at 09:35
  • Well, then `arrayOfTuples map {case (i, s) => i.toString + s}` is, of course, more handy. However, you should ask the question you have, to get the answer you need. :) – user unknown Aug 02 '11 at 09:49
  • Well, as he said "frequently", I hope it means "in different cases" i don't see any scenario where you frequently need an `Int + String` mapping. ;) – Nicolas Aug 02 '11 at 10:29
8

Another option is

arrayOfTuples.map { 
    t => 
    val (e1,e2) = t
    e1.toString + e2
}
Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
6

Starting in Scala 3, parameter untupling has been extended, allowing such a syntax:

// val tuples = List((1, "Two"), (3, "Four"))
tuples.map(_.toString + _)
// List[String] = List("1Two", "3Four")

where each _ refers in order to the associated tuple part.

Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
2

I think for comprehension is the most natural solution here:

for ((e1, e2) <- arrayOfTuples) yield {
  e1.toString + e2
}
Yahor
  • 639
  • 8
  • 16