0

I want to zip two list and do a pattern matching, but it seems zip and match produce error. I do not know understand why there is such error.

The following example is a simplified version.

This works

val l = List((1, 2), (3, 4), (5, 6))
l.map { case(a, b) => println(s"First is $a, second is $b") }

This does not work

val l1 = List(1,2,3)
val l2 = List(4,5,6)
l1.zip(l2)
l1.zip(l2).map { case(a, b) => a match {case 1 => println(s"First is $a, second is $b") }}

Error info

scala.MatchError: 2 (of class java.lang.Integer)
  at .$anonfun$res15$1(<console>:14)
  at .$anonfun$res15$1$adapted(<console>:14)
  at scala.collection.immutable.List.map(List.scala:287)
  ... 28 elided
Jill Clover
  • 2,168
  • 7
  • 31
  • 51

3 Answers3

2

zip works with match just fine, but if you use map() then you have to provide a match for all conditions you are going to encounter. That's where a default case comes in handy.

If you're really only interested in the case where a == 1, and you simply want to ignore all other conditions, then use collect() instead of map().

l1.zip(l2).collect{case (1, b) => println(s"First is 1, second is $b")}

This works because collect() takes a partial function as it's parameter, so input that matches its case is good and everything else is ignored. map(), on the other hand, take a function (not partial) as its parameter, which means that it must accept and process all inputs, so if you're using pattern matching then there must be a match for every situation.

jwvh
  • 50,871
  • 7
  • 38
  • 64
0

Your compiler should have nicely warned about "You are missing default pattern match which is case _ =>".

It has nothing to do with zip but instead with "pattern matching".

Working example;

scala> List(1,2,3).zip(List(4,5,6)).map { case(a, b) => 
        a match {case 1 => println(s"First is $a, second is $b") 
                 case _ => println("Oops I missed it")}}

First is 1, second is 4
Oops I missed it
Oops I missed it
res5: List[Unit] = List((), (), ())

Also if you are simply printing, use foreach function not map because mathematically map is supposed to return you some data back. foreach is fire and forget.

scala> List(1,2,3).zip(List(4,5,6)).foreach { case(a, b) => 
          a match { 
             case 1 => println(s"First is $a, second is $b") 
             case _ => println("Oops I missed it")}}

First is 1, second is 4
Oops I missed it
Oops I missed it

Also read - Scala case match default value

And Chapter - 9, Pattern matching/ stackoverflow doc

prayagupa
  • 30,204
  • 14
  • 155
  • 192
-2

You are missing a pair of brackets that's all

@ val list1 = List(1, 2, 3)
val llist1: List[Int] = List(1, 2, 3)
@ val list2 = List(5, 6, 7)
lislist2: List[Int] = List(5, 6, 7)
@ list1.zip(list2)
res2: List[(Int, Int)] = List((1, 5), (2, 6), (3, 7))

@ list1.zip(list2) foreach { case ((a, b)) => println(s"first is $a and then is $b") }

this outputs

first is 1 and then is 5
first is 2 and then is 6
first is 3 and then is 7

The code is the same as what you wrote except that I use one extra ( and this ) to patch the tuple.

Knows Not Much
  • 30,395
  • 60
  • 197
  • 373