Here is a method that takes two lists (l1
and l2
) and pairs up elements that "match". As you can see at the end of the code block these lists consist of matching elements but in different indexes. The method pairUp
outputs matching elements paired up, and discards those without a pair.
I spent way too much time writing this method, and it feels clumsy and complex, not scala idiomatic.
How could I have done this simpler? and could I make it faster?
case class A(serial:Int) {
def matches(b:B):Boolean = this.serial == b.serial
}
case class B(serial:Int)
import scala.annotation.tailrec
@tailrec def pairUp(
list1:List[A],
list2:List[B],
i:Int=0,
pairs:List[(A, B)]=List.empty[(A,B)]
):List[(A,B)] = {
if (list1.isEmpty || list2.isEmpty) return pairs
else {
if (i == list2.length) // this list1 element has no match
return pairUp(
list1.tail, // so discard
list2,
0, // reset counter
pairs)
else {
if (list1.head matches list2.head) // these elements match
return pairUp(
list1.tail,
list2.tail,
0,
pairs :+ ((list1.head, list2.head)))
else
return pairUp(
list1,
list2.tail :+ list2.head, // list2 element to back
i + 1,
pairs)
}
}
}
val l1 = List(0, 1, 2, 3, 4, 5).map(A(_))
val l2 = List(1, 3, 0, 2, 4).map(B(_))
val pairs = pairUp(l1, l2)
// List((A(0),B(0)), (A(1),B(1)), (A(2),B(2)), (A(3),B(3)), (A(4),B(4)))
println(pairs)