I have an Option[String].
I want to check if there is a string exists and if it's exists its not blank.
def isBlank( input : Option[String]) : Boolean =
{
input.isEmpty ||
input.filter(_.trim.length > 0).isEmpty
}
Is there is a better way of doing this in Scala ?
What you should do is check using exists. Like so:
myOption.exists(_.trim.nonEmpty)
which will return True if and only if the Option[String] is not None and not empty.
An approach based in pattern matching,
def isBlank( input : Option[String]) : Boolean =
input match {
case None => true
case Some(s) => s.trim.isEmpty
}
This should work as well since filter of an empty Option results in an empty Option
def isBlank( input : Option[String]) : Boolean =
input.filter(_.trim.length > 0).isEmpty
All proposed solutions will crash with NullPointerException if you pass:
val str : Option[String] = Some(null).
Therefore null-check is a must:
def isBlank(input: Option[String]): Boolean =
input.filterNot(s => s == null || s.trim.isEmpty).isEmpty
exists (Accepted solution) will work when input has at least one element in it, that is Some("") but not when it's None.
exists checks if at least one element(x) applies to function.
eg.
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
Same happens with Option.empty, as theres no element in it,
scala> Option.empty[String].exists(_.isEmpty)
res33: Boolean = false
So forall is what makes sure the the function applies all the elements.
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
The gross way is to filter nonEmpty string, then check 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
I am from C# background and found Scala implicit methods similar to C# extensions
import com.foo.bar.utils.MyExtensions._
...
"my string".isNullOrEmpty // false
"".isNullOrEmpty // true
" ".isNullOrEmpty // true
" ".isNullOrEmpty // true
val str: String = null
str.isNullOrEmpty // true
Implementation
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)
}
You can also take advantage of Extractor pattern. It makes codes much more declarative.
For example:
object NonBlank {
def unapply(s: String): Option[String] = Option(s).filter(_.trim.nonEmpty)
}
And then use it like
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."))
}
I added a Scalafiddle to play with that: Scalafiddle
That shows the marked correct answer is wrong (as pointed out by prayagupd):
def isBlank(str: Option[String]): Boolean =
str.forall(_.trim.isEmpty)
the solution is for non-blank:
def isNotBlank(str: Option[String]): Boolean =
str.exists(_.trim.nonEmpty)
来源:https://stackoverflow.com/questions/24086493/check-if-a-string-is-blank-or-doesnt-exist-in-scala