Je suis souvent en train d'écrire du code qui compare deux objets et produit une valeur sur la base de leur identique, ou différente, sur la base de la manière dont elles sont différentes.
Donc, je pourrais écrire: P>
class OneAndOnlyOne[T](predicate: T => Boolean) { def unapply( pair: Pair[T,T] ): Option[T] = { val (item1,item2) = pair val v1 = predicate(item1) val v2 = predicate(item2) if ( v1 != v2 ) Some( if ( v1 ) item1 else item2 ) else None } }
6 Réponses :
Que diriez-vous de cela:
Welcome to Scala version 2.8.0.r20327-b20091230020149 (Java HotSpot(TM) Client VM, Java 1.6.0_17). Type in expressions to have them evaluated. Type :help for more information. scala> def m(v1: Any,v2: Any) = (v1,v2) match { | case (Some(x),Some(y)) => "a" | case (Some(_),None) | (None,Some(_)) => "b" | case _ => "c" | } m: (v1: Any,v2: Any)java.lang.String scala> m(Some(1),Some(2)) res0: java.lang.String = a scala> m(Some(1),None) res1: java.lang.String = b scala> m(None,None) res2: java.lang.String = c scala>
Cela semble assez simple, je pense que j'ai essayé cela à Scala 2.7 et cela ne compila pas, je vais essayer à nouveau.
Vous devriez pouvoir le faire si vous le définissez en tant que Val d'abord: comme indiqué par le nom, le nom du VAL contenant l'objet extracteur doit être capitalisé. < / p> p>
Expressions régulières comme des cas sont utilisés de la même manière.
Merci Mitch, j'ai fait en fait essayer cela, et je pense que cela a échoué parce que je n'avais pas mon Val capitalisé .. intéressant.
Je pense que vous posez deux questions légèrement différentes.
Une question est de savoir comment utiliser "ou" dans les relevés de commutation. || ne fonctionne pas; | Est-ce que. Et vous ne pouvez pas utiliser de variables dans ce cas (car en général, ils peuvent correspondre à différents types, ce qui rend le type déroutant). Donc: P>
class DiOption[+T] { def trinary = this } case class Both[T](first: T, second:T) extends DiOption[T] { } case class OneOf[T](it: T) extends DiOption[T] { } case class Neither() extends DiOption[Nothing] { } implicit def sometuple2dioption[T](t2: (Option[T],Option[T])): DiOption[T] = { t2 match { case (Some(x),Some(y)) => Both(x,y) case (Some(x),None) => OneOf(x) case (None,Some(y)) => OneOf(y) case _ => Neither() } } // Example usage val a = (Some("This"),None) a trinary match { case Both(s,t) => "Both" case OneOf(s) => "Just one" case _ => "Nothing" }
Salut Rex, qui semble prometteur, mais cela ne s'étend pas (encore) à d'autres situations, par exemple. Là où on ne demande pas l'un d'entre eux d'être défini, mais pour que l'un d'entre eux de dire "soit un nombre uniforme" ou "avoir une valeur> 10".
Ne: pas: cas (certains (x), certains (y)) si ((x> 10) && (y iseven)) => "les deux" travail?
Je ne suis pas sûr que je suive Jim, mais: Oui, cela fonctionne, mais je ne pense pas que ce que je dis. J'aimerais conceptuellement faire ceci: cas (OneEven) => cas (BotteEeven) =>. Par exemple. Qu'ils soient même ou non, c'est juste un test différent de savoir s'il n'est pas à la fois ou non pas aucun.
sur SCALAA 2.8:
val result = (List(v1,v2).flatten : List[Int]) match { case List(value1, value2) => "a" case List(value) => "b" case _ = > "c" }
Merci pour la réponse Daniel, qui semble bien mais ne fonctionne que pour le prédicat "x => x.isdefinefin", je ne pouvais pas l'utiliser pour dire "x => x% 2 == 0" pour vérifier si un seul et un seul des deux articles était même.
@Alex - Vous pouvez l'exprimer comme ceci: Liste (V1, V2) Filtre (_% 2 == 0) Match {Liste des cas (Valeur1, Value2) => "A" Liste de cas (valeur) => " b "cas _ =>" c "} code>
Filtrer la liste en premier. Je pense que la solution de Daniel est la plus étroite en avant.
@ALEX: Je suppose que vous pouvez extraire le modèle: def xmatch (valeurs: liste [T], F: T => Boolean, P: liste [Partialfunction [T, X]]) Code> .
@ALEX: J'ai un peu bricolé avec un peu: Stackoverflow.com/Questtions/2039715/...
Si vous devez prendre en charge des prédicats arbitraires, vous pouvez en dériver de ceci (qui est basé sur L'idée de Daniel ): la définition de la fonction: p> Maintenant, vous pouvez l'utiliser comme ceci: p> Je ne suis pas si sûr si c'est une bonne idée (c'est-à-dire lisible). Mais un exercice soigné néanmoins. P> Ce serait bien si vous pouviez correspondre à des tuples: cas (valeur1, valeur2) => ... code> au lieu de listes. P> p>
Homme, j'aime Scala. Il ne pouvait pas être plus lisible, et c'est une fonction i>. Et une doublure, à cela.
Depuis que vous avez déjà assorté contre (certains (x), certains (y), vous pouvez correspondre à (aucun, aucun) explicitement, et les cas restants sont (certains (x), aucun) et (aucun, certains ( y)):
def decide [T](v1: Option[T], v2:Option[T]) = (v1, v2) match { case (Some (x), Some (y)) => "a" case (None, None) => "c" case _ => "b" } val ni : Option [Int] = None decide (ni, ni) // c decide (Some (4), Some(3)) // a decide (ni, Some (3)) // b decide (Some (4), ni) // b
Avez-vous un cas d'utilisation indiquant pourquoi vous voulez faire cela? Peut-être qu'une meilleure solution existe à l'aide de
soit code>
Cas d'utilisation - surtout je veux juste éviter d'écrire les deux cas par ex. (certains, aucun) et (aucun, certains). Mon cas d'utilisation générale est que je comparais deux produits sur une caractéristique particulière, et peut-être que les deux produits ont la caractéristique, ou seulement l'un d'entre eux, ou s'ils l'ont tous deux, peut-être que l'on a une bonne valeur pour cette caractéristique et un pauvre valeur.
Dupliqué possible de Match de plusieurs classes de cas dans Scala