Ответ 1
Что вам нужно сделать, это проверить с помощью exists
. Например:
myOption.exists(_.trim.nonEmpty)
который вернет True
тогда и только тогда, когда Option[String]
не None
и не пуст.
У меня есть Option[String]
.
Я хочу проверить, существует ли строка, и если она существует, она не является пустой.
def isBlank( input : Option[String]) : Boolean =
{
input.isEmpty ||
input.filter(_.trim.length > 0).isEmpty
}
Есть ли лучший способ сделать это в Scala?
Что вам нужно сделать, это проверить с помощью exists
. Например:
myOption.exists(_.trim.nonEmpty)
который вернет True
тогда и только тогда, когда Option[String]
не None
и не пуст.
Подход, основанный на сопоставлении шаблонов,
def isBlank( input : Option[String]) : Boolean =
input match {
case None => true
case Some(s) => s.trim.isEmpty
}
Это должно сработать, так как фильтр пустого варианта приводит к пустой опции
def isBlank( input : Option[String]) : Boolean =
input.filter(_.trim.length > 0).isEmpty
Все предлагаемые решения будут сбой с NullPointerException, если вы передадите:
val str : Option[String] = Some(null).
Поэтому null-check - это must:
def isBlank(input: Option[String]): Boolean =
input.filterNot(s => s == null || s.trim.isEmpty).isEmpty
exists
(принятое решение) будет работать, если на входе имеется хотя бы один элемент, то есть Some("")
, но не когда он None
.
exists
проверяет, применяется ли по крайней мере к одному элементу (x
).
например.
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
То же самое происходит с Option.empty
, поскольку в нем нет элемента,
scala> Option.empty[String].exists(_.isEmpty)
res33: Boolean = false
Итак, forall
- это то, что гарантирует, что функция применяет все элементы.
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
Общий способ заключается в фильтрации строки nonEmpty
, затем проверьте 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
Я из фона С# и нашел Scala неявные методы, похожие на расширения С#
import com.foo.bar.utils.MyExtensions._
...
"my string".isNullOrEmpty // false
"".isNullOrEmpty // true
" ".isNullOrEmpty // true
" ".isNullOrEmpty // true
val str: String = null
str.isNullOrEmpty // true
Реализация
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)
}
Вы также можете воспользоваться шаблоном экстрактора. Это делает коды намного более декларативными.
Например:
object NonBlank {
def unapply(s: String): Option[String] = Option(s).filter(_.trim.nonEmpty)
}
А затем используйте его как
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."))
}
Я добавил Scalafiddle, чтобы играть с этим: Scalafiddle
Это показывает, что правильно обозначенный правильный ответ неверен (как указано в файле молитвы):
def isBlank(str: Option[String]): Boolean =
str.forall(_.trim.isEmpty)
решение для непустого:
def isNotBlank(str: Option[String]): Boolean =
str.exists(_.trim.nonEmpty)