2017-10-17 35 views
0

Supposons que je suis en train d'écrire une fonction zip deux listes que si elles sont de la même taille et autrement, ne:Comment faire pour zipper des listes seulement si elles sont de la même taille et échouer si leurs tailles diffèrent?

def foo(xs: List[Int], ys: List[Int]): Either[String, List[(Int, Int)]] = 
    if (xs.size == ys.size) Right(xs zip ys) else Left(s"$xs and $ys have different sizes") 

Il fonctionne, mais je n'aime pas utiliser if. Comment amélioreriez-vous le code ci-dessus?

+4

me semble bon. Vous devez utiliser la condition de toute façon. L'alternative pourrait être la correspondance de modèle sur la taille, mais je ne pense pas qu'elle apporte beaucoup de valeur 'def foo (xs: Liste [Int], ys: Liste [Int]): Soit [Chaîne, Liste [(Int, Int)]] = xs.size == ys.size match {case vrai => Droite (xs zip ys) case faux => Left (s "$ xs et $ ys ont des tailles différentes")} ' – prayagupd

Répondre

2

Vous pouvez utiliser pattern matching si pour une raison quelconque, vous ne l'aimez pas if

def zip(as: List[Int], bs: List[Int]): Either[String, List[(Int, Int)]] = (as, bs) match { 
    case (Nil, Nil) => Right(Nil) 
    case (a :: as1, b :: bs1) => for { 
     t <- zip(as1, bs1) 
    } yield (a, b) :: t 
    case _ => Left(s"$as and $bs have different sizes") 
    } 

ou

def zip(as: List[Int], bs: List[Int]): Either[String, List[(Int, Int)]] = { 
    @tailrec 
    def loop(as1: List[Int], bs1: List[Int], acc: List[(Int, Int)]): Either[String, List[(Int, Int)]] = (as1, bs1) match { 
     case (Nil, Nil) => Right(acc) 
     case (a :: as2, b :: bs2) => loop(as2, bs2, (a, b) :: acc) 
     case _ => Left(s"$as and $bs have different sizes") 
    } 

    loop(as, bs, Nil).map(_.reverse) 
    }