J'ai un Option[String]
.
Je veux vérifier s'il existe une chaîne et si elle existe, elle n'est pas vide.
def isBlank( input : Option[String]) : Boolean =
{
input.isEmpty ||
input.filter(_.trim.length > 0).isEmpty
}
Existe-t-il une meilleure façon de le faire dans Scala?
Ce que vous devez faire est de vérifier en utilisant exists
. Ainsi:
myOption.exists(_.trim.nonEmpty)
qui renverra True
si et seulement si le Option[String]
n'est pas None
et n'est pas vide.
Une approche basée sur la correspondance de motifs,
def isBlank( input : Option[String]) : Boolean =
input match {
case None => true
case Some(s) => s.trim.isEmpty
}
Cela devrait également fonctionner car le filtre d'une option vide entraîne une option vide
def isBlank( input : Option[String]) : Boolean =
input.filter(_.trim.length > 0).isEmpty
exists
(solution acceptée) fonctionnera quand l'entrée contient au moins un élément, c'est-à-dire Some("")
mais pas quand c'est None
.
exists
vérifie si au moins un élément (x
) s'applique à la fonction.
par exemple.
scala> List[String]("Apple", "").exists(_.isEmpty)
res21: Boolean = true
//if theres no element then obviously returns false
scala> List[String]().exists(_.isEmpty)
res30: Boolean = false
La même chose se produit avec Option.empty
, comme il n'y a aucun élément dedans,
scala> Option.empty[String].exists(_.isEmpty)
res33: Boolean = false
Donc forall
est ce qui garantit que la fonction applique tous les éléments.
scala> def isEmpty(sOpt: Option[String]) = sOpt.forall(_.trim.isEmpty)
isEmpty: (sOpt: Option[String])Boolean
scala> isEmpty(Some(""))
res10: Boolean = true
scala> isEmpty(Some("non-empty"))
res11: Boolean = false
scala> isEmpty(Option(null))
res12: Boolean = true
La manière grossière est de filtrer la chaîne nonEmpty
, puis de vérifier option.isEmpty
.
scala> def isEmpty(sOpt: Option[String]) = sOpt.filter(_.trim.nonEmpty).isEmpty
isEmpty: (sOpt: Option[String])Boolean
scala> isEmpty(None)
res20: Boolean = true
scala> isEmpty(Some(""))
res21: Boolean = true
Toutes les solutions proposées planteront avec NullPointerException si vous réussissez:
val str : Option[String] = Some(null).
Par conséquent, le contrôle nul est un doit:
def isBlank(input: Option[String]): Boolean =
input.filterNot(s => s == null || s.trim.isEmpty).isEmpty
Je viens du milieu C # et j'ai trouvé Scala méthodes implicites similaires aux extensions C #
import com.foo.bar.utils.MyExtensions._
...
"my string".isNullOrEmpty // false
"".isNullOrEmpty // true
" ".isNullOrEmpty // true
" ".isNullOrEmpty // true
val str: String = null
str.isNullOrEmpty // true
Mise en œuvre
package com.foo.bar.utils
object MyExtensions {
class StringEx(val input: String) extends AnyVal {
def isNullOrEmpty: Boolean =
if (input == null || input.trim.isEmpty)
true
else
false
}
implicit def isNullOrEmpty(input: String): StringEx = new StringEx(input)
}
Vous pouvez également profiter de modèle d'extracteur . Cela rend les codes beaucoup plus déclaratifs.
Par exemple:
object NonBlank {
def unapply(s: String): Option[String] = Option(s).filter(_.trim.nonEmpty)
}
Et puis utilisez-le comme
def createUser(name: String): Either[Error, User] = name match {
case NonBlank(username) => Right(userService.create(username))
case _ => Left(new Error("Invalid username. Blank usernames are not allowed."))
}
J'ai ajouté un Scalafiddle pour jouer avec ça: Scalafiddle
Cela montre que la bonne réponse marquée est erronée (comme l'a souligné Prayagupd):
def isBlank(str: Option[String]): Boolean =
str.forall(_.trim.isEmpty)
la solution est pour non vide:
def isNotBlank(str: Option[String]): Boolean =
str.exists(_.trim.nonEmpty)