Search code examples
scaladictionaryzip

zipWith in Scala using map


Define zipWith. It should zip two lists, but instead of zipping elements into a tuple, it should use a function to combine two elements.

Example: zipWith(List(1, 2, 3), List(10, 11, 12), (x: Int, y: Int) => x+y) Should return: List(11,13,15)

use map and zip.

def zipWith[A,B,C](xs: List[A], ys: List[B], f: (A, B) => C): List[C] = {
        val zs = xs.zip(ys)
        //I don't know how to do this because if myMap(zs, f) 

        //myMap takes a functin f:(a)=>b instead of f: (A, B) => C
    }
}

Solution

  • It sounds like you looking for something like this:

    def zipWith[A,B,C](xs: List[A], ys: List[B], f: (A, B) => C): List[C] = {
      (xs, ys) match {
        case (Nil, _) => Nil
        case (_, Nil) => Nil
        case (x :: xs, y :: ys) => f(x, y) :: zipWith(xs, ys, f)
      }
    }
    

    Hope that helps.

    Update

    Here is the same function but being tail-recursive:

        def zipWith[A, B, C](xs: List[A], ys: List[B], f: (A, B) => C): List[C] = {
          @tailrec
          def zipAccumulatingResult(xs: List[A], ys: List[B], f: (A, B) => C, acc: List[C]): List[C] = {
            (xs, ys) match {
              case (Nil, _) => acc
              case (_, Nil) => acc
              case (x :: xs, y :: ys) => zipAccumulatingResult(xs, ys, f, acc :+ f(x, y))
            }
          }
    
          zipAccumulatingResult(xs, ys, f, Nil)
        }