Reputation: 5376
Why is the following code does not work, and how can I overcome it using Iterator
?
def f(str : String) : (String, String) = {
str.splitAt(1)
}
var with_id : Iterator[(String, Int)] = List(("test", 1), ("list", 2), ("nothing", 3), ("else", 4)).iterator
println(with_id.mkString(" "))
val result = with_id map { (s : String, i : Int) => (f(s), i) }
println(result.mkString(" "))
Expected output is:
(("t", "est"), 1) (("l", "ist"), 2) ...
Error:
Error:(28, 54) type mismatch;
found : (String, Int) => ((String, String), Int)
required: ((String, Int)) => ?
val result = with_id map { (s : String, i : Int) => (f(s), i) }
^
Upvotes: 0
Views: 76
Reputation: 6132
with_id.map
expects a ((String, Int) => ?)
function as input. That is, a function that takes a Tuple
as input, not two parameters.
You can use it like this:
with_id map{ case (s,i) => (f(s), i)} //match the input tuple to s and i
Upvotes: 1
Reputation: 24812
The problem is that (s : String, i : Int) => (f(s), i)
is a Function2
(i.e a function that takes 2 arguments):
scala> (s : String, i : Int) => (f(s), i)
res3: (String, Int) => ((String, String), Int) = <function2>
whereas .map
expects a Function1
(taking a tuple as its argument).
You could define a Function1
with
scala> val g = (t: (String, Int)) => (f(t._1), t._2)
g: ((String, Int)) => ((String, String), Int) = <function1>
scala> val result = with_id map g
result: Iterator[((String, String), Int)] = non-empty iterator
But it seems much better (to me at least) to use the more idiomatic pattern matching anonymous function (note the added case
) :
scala> val result = with_id map { case (s : String, i : Int) => (f(s), i) }
result: Iterator[((String, String), Int)] = non-empty iterator
Upvotes: 2