Grab first successful pair from a list of maps I have a function that parses geographic coordinates through a list of different providers. In this case I want to look up two addresses. The main problem of this question is - given a List of of Geocode Service -> Resolved Address mappings, find the first successful pair that has a valid resolved address. 

So each address results in a map(provider -> result). I'm given a list of them, and need to find the a successful pair from the list e.g provider1 from the first address and provider1 from the second address. I can't compare the resolved addresses if the providers do not match. 

For example, the best scenario is that the addresses are perfect. I can use the head map entry of the first address and query the map entry for the second address. Then compare their values. However, it's rarely that simple. 

I started out with a foldLeft, but I feel that can be inefficient if it matches successfully immediately. 

val result: List[Map[GeoProviders.GeoProvider, Either[GeoCodeErrors.GeocodeError, PostalAddress]]]
                  result match {
                    case firstAddressOption :: secondAddressOption :: Nil =&gt; {
                      firstAddressOption.foldLeft[Option[Double]](None)((result, address1: (GeoProvider, Either[GeocodeError, PostalAddress])) =&gt; {
                        result match {
                          case Some(_) =&gt; result
                          case None =&gt;
                            val address2 = secondAddressOption.get(address1._1)
                            (address1._2, address2) match {
                              case  (Right(successAddr1), Some(Right(successAddr2))) =&gt; {
                                (successAddr1.coordinates, successAddr2.coordinates) match {
                                  case (Some(firstCoord), Some(secondCoord)) =&gt; {
                                    Some(haversineDistance((firstCoord.latitude, firstCoord.longitude), (secondCoord.latitude, secondCoord.longitude)))
                                  }
                                  case _ =&gt; None
                                }
                              }
                            }
                        }
                      })
You can use find to avoid folding over an entire map, something like:

map1.find {
  case (k, Right(addr1)) =&gt;
    map2.get(k) match {
      case Some(Right(addr2)) =&gt; true
      case _ =&gt; false
    }
  case _ =&gt; false
} match {
  case Some((k, Right(addr1))) =&gt;
    map2.get(k) match {case Some(Right(addr2)) =&gt; Some(haversineDistance(addr1, addr2))}
  case _ =&gt; None
}


(I renamed first/secondAddressOption to map1/map2 to save some typing)

An alternative approach, which doesn't necessarily improve performance but does make the code shorter and more reusable, is to create a method that combines two maps by key:

def combineMaps[K, V](map1: Map[K, V], map2: Map[K, V]): Map[K, List[V]] =
  // To improve performance, compare the sizes of map1 and map2
  // and fold over the smaller map.
  map1.foldLeft(map2.mapValues(List(_))) {
    case (map2, (k, x)) =&gt; map2.updated(k, x :: map2.get(k).toList.flatten)
  }


Then use collectFirst on the combined map:

combineMaps(map1, map2).collectFirst {
  case (_, Right(addr1) :: Right(addr2) :: Nil) =&gt; haversineDistance(addr1, addr2)
}