39 votes

Scala dispose-t-il d'une méthode de bibliothèque pour construire des Option-s qui tiennent compte des chaînes vides ?

Je veux filtrer les chaînes vides pour les mettre dans une Option. J'ai donc rapidement construit ceci maintenant :

def StrictOption(s: String) = s match {
  case s if s != null && s.trim.length() > 0 => Some(s)
  case _ => None
}

Question : est-ce que cela se trouve déjà quelque part dans la bibliothèque standard ?

114voto

Ben James Points 41165

Je ne pense pas qu'il y ait une seule méthode dans la bibliothèque standard pour faire cela, mais vous pouvez le faire de manière beaucoup plus concise que votre implémentation.

Option(s).filter(_.trim.nonEmpty)

9voto

Luigi Plinge Points 23552

Si vous vous souciez des performances, alors

if (s.trim.isEmpty) None else Some(s)

est seulement 4 caractères plus long que la solution de Ben James, et s'exécute 3 fois plus vite, dans mon benchmark (47 vs 141).

6voto

Xavier Guihot Points 6414

Démarrage Scala 2.13 pour ceux qui ne s'y attendent pas null (contexte non-Java), Option::unless y Option::when sont désormais une option alternative :

// val str = "hello"
Option.unless(str.isEmpty)(str)
// Option[String] = Some(hello)
Option.when(str.nonEmpty)(str)
// Option[String] = Some(hello)

// val str: String = ""
Option.unless(str.isEmpty)(str)
// Option[String] = None
Option.when(str.nonEmpty)(str)
// Option[String] = None

5voto

Rex Kerr Points 94401

Il n'y a rien d'intégré ; le filtre de Ben est la meilleure version sommaire si les performances ne sont pas un problème (par exemple, si vous validez l'entrée de l'utilisateur). En général, les performances ne sont pas un problème.

Notez également qu'il est un peu étrange d'utiliser match alors qu'il ne s'agit pas de faire correspondre quoi que ce soit ; il s'agit simplement d'un texte passe-partout supplémentaire pour obtenir une instruction if-else. Dites simplement

if (s ne null && s.trim.length > 0) Some(s) else None

ce qui est à peu près aussi rapide et bref que tout, à moins que vous ne vouliez écrire votre propre méthode is-it-whitespace. Notez que trim utilise un critère particulier : tout ce qui est au-dessus de \u0020 (c'est-à-dire ' ') n'est pas rogné, et tout ce qui est égal ou inférieur l'est. Ainsi, vous pourriez également écrire votre propre détecteur de chaîne coupée est vide, si la performance de cette opération était particulièrement importante :

def ContentOption(s: String): Option[String] = {
  if (s ne null) {
    var i = s.length-1
    while (i >= 0) {
      if (s.charAt(i) > ' ') return Some(s)
      i -= 1
    }
  }
  None
}

0voto

darrenmc Points 553

Cela pourrait également être réalisé avec une for-compréhension

val res = for (v <- Option(s) if s.nonEmpty) yield v

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X