Scala convert Option[T] to String - scala

Does exist any native function in scala that does the equivalent this?
def strConvert[T](v: Option[T]): String = {
if (v.isDefined)
v.get.toString
else
""
}

For generic T, you can avoid the if with map -- v.map(_.toString).getOrElse("")

scala> Some(1).fold("")(_.toString)
res0: String = 1
scala> None.fold("")(_.toString)
res1: String = ""

Option is a monad. In FP, when working with monads, you define what you want to happen if the monad contains a state (i.e. a value other than None). Otherwise, you move on.
val ostring: Option[String] = functionThatGetsOptionString()
ostring.map { s =>
functionThatUsesString(s)
}
Within the map function, s will contain the raw string if the Option is Some(String) otherwise it won't execute the inner body if Option is None.

Related

Return second string if first is empty?

Here is an idiom I find myself writing.
def chooseName(nameFinder: NameFinder) = {
if(nameFinder.getReliableName.isEmpty) nameFinder.getReliableName
else nameFinder.secondBestChoice
}
In order to avoid calling getReliableName() twice on nameFinder, I add code that makes my method look less elegant.
def chooseName(nameFinder: NameFinder) = {
val reliableName = nameFinder.getReliableName()
val secondBestChoice = nameFinder.getSecondBestChoice()
if(reliableName.isEmpty) reliableName
else secondBestChoice
}
This feels dirty because I am creating an unnecessary amount of state using the vals for no reason other than to prevent a duplicate method call. Scala has taught me that whenever I feel dirty there is almost always a better way.
Is there a more elegant way to write this?
Here's two Strings, return whichever isn't empty while favoring the first
There's no need to always call getSecondBestChoice, of course. Personally, I find nothing inelegant about the code after changing that - it's clear what it does, has no mutable state. The other answers just seem overcomplicated just to avoid using a val
def chooseName(nameFinder: NameFinder) = {
val reliableName = nameFinder.getReliableName()
if(reliableName.isEmpty) reliableName
else nameFinder.getSecondBestChoice()
}
If you really want to avoid the val, here's another variant (generalises well if there are more than two alternatives)
List(nameFinder.getReliableName(), nameFinder.getSecondBestChoice()).find(_.nonEmpty).get
(or getOrElse(lastResort) if everything in the list may be empty too)
Here's a way using Option. It's not that much prettier, but everything is called only once. This assumes you want a String as a result, and don't care if the second string is empty.
Some(nameFinder.getReliableName)
.filter(_.nonEmpty)
.getOrElse(nameFinder.secondBestChoice)
Option(namefinder.getReliableName) // transforms a potential null into None
.filter(_.trim.nonEmpty) // "" is None, but also " "
.getOrElse(nameFinder.secondBestChoice)
Or better, if you can modify getReliableName to return an Option[String]:
def chooseName(nameFinder: NameFinder): String =
namefinder.getReliableName getOrElse nameFinder.secondBestChoice
Finally, if secondBestChoice can fail as well (assuming it returns an Option[String]):
def chooseName(nameFinder: NameFinder): Option[String] =
namefinder.getReliableName orElse nameFinder.secondBestChoice
If you need it more than once:
scala> implicit class `nonempty or else`(val s: String) extends AnyVal {
| def nonEmptyOrElse(other: => String) = if (s.isEmpty) other else s }
defined class nonempty
scala> "abc" nonEmptyOrElse "def"
res2: String = abc
scala> "" nonEmptyOrElse "def"
res3: String = def
Using the following pattern matching may deliver a neater scalish code,
def chooseName(nameFinder: NameFinder) = {
nameFinder.getReliableName match {
case r if r.isEmpty => r
case _ => nameFinder.secondBestChoice
}
}

In Scala, can you make an anonymous function have a default argument?

This works:
scala> def test(name: String = "joe"): Boolean = true
test: (name: String)Boolean
I expected this to work in the same way:
scala> val test: String => Boolean = { (name: String = "joe") => true }
console>:1: error: ')' expected but '=' found.
The boring, correct answer is no, you can't, but actually you kind of can, with the experimental single abstract method (SAM) synthesis in 2.11.
First you need to define your own SAM type with the default value for the apply method's parameter:
trait Func {
def apply(name: String = "joe"): Boolean
}
Now you can use the function literal notation to define a Func (note that you'll need to have started the REPL with -Xexperimental for this step to work):
val f: Func = { (name: String) => name == "joe" }
Or just:
val f: Func = _ == "joe"
And then the usual stuff:
scala> f("joe")
res0: Boolean = true
scala> f("eoj")
res1: Boolean = false
And the punchline:
scala> f()
res2: Boolean = true
It's not exactly the syntax you're asking for, and there are no promises that this will ever leave experimental status, and even if it does, default arguments may not be supported—but I still think it's pretty neat that it works now.
To expand on "The boring, correct answer is no" in Travis Brown's answer:
Functions (i.e. objects of FunctionN[...] type) can't have default arguments in Scala, only methods can. Since anonymous function expressions produce functions (and not methods), they can't have default arguments.
This is bit dirty solution I think, using currying
def testDef(nameDef: String)(name2: String): Boolean = {
val name3 = if ( name2 != "") name2 else nameDef
//use name3 for your logic
true
}
//> testDef: (name: String)(name2: String)Boolean
Curry the testDef method to hold default value as shown below.
var test = test("joe")_ //> test : String => Boolean=function1
test("fun") //"fun" will be used as name3
test("") // "joe" will be used as name3

“Convert” Option[x] to x

I working with play for Scala (2.1) and I need to convert an Option[Long] value to Long.
I know how to do the opposite, I mean:
def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)
But in my case, I have to pass a value of Option[Long] as a type into a method that takes Long.
If you have x as Option[Long], x.get will give you Long.
First of all, your implementation of "the opposite" has some serious problems. By putting a type parameter named Long on the method you're shadowing the Long type from the standard library. You probably mean the following instead:
def toOption(value: Long): Option[Long] =
if (value == null) None else Some(value)
Even this is kind of nonsensical (since scala.Long is not a reference type and can never be null), unless you're referring to java.lang.Long, which is a recipe for pain and confusion. Finally, even if you were dealing with a reference type (like String), you'd be better off writing the following, which is exactly equivalent:
def toOption(value: String): Option[String] = Option(value)
This method will return None if and only if value is null.
To address your question, suppose we have the following method:
def foo(x: Long) = x * 2
You shouldn't generally think in terms of passing an Option[Long] to foo, but rather of "lifting" foo into the Option via map:
scala> val x: Option[Long] = Some(100L)
x: Option[Long] = Some(100)
scala> x map foo
res14: Option[Long] = Some(200)
The whole point of Option is to model (at the type level) the possibility of a "null" value in order to avoid a whole class of NullPointerException-y problems. Using map on the Option allows you to perform computations on the value that may be in the Option while continuing to model the possibility that it's empty.
As another answer notes, it's also possible to use getOrElse to "bail out" of the Option, but this usually isn't the idiomatic approach in Scala (except in cases where there really is a reasonable default value).
This method is already defined on Option[A] and is called get :
scala> val x = Some(99L)
x: Some[Long] = Some(99)
scala> x.get
res0: Long = 99
The problem is that calling get on None will throw a NoSucheElement Exception:
scala> None.get
java.util.NoSuchElementException: None.get
thus you will not gain any benefits from using an Option type.
Thus as stated before you can use getOrElse if you can provide a sensible default value or handle the Exception.
The idiomatic scala way would be using map or a for-comprehension
x map (_ + 1)
res2: Option[Long] = Some(100)
or
for (i <- x) yield i +1
res3: Option[Long] = Some(100)
Option is way to localise side-effect (your function can return empty value). And good style to lift your computation to Option (Option is Monad with map & flatMap methods).
val x = Option[Long](10)
x.map { a => a + 10 }
And extract value with manually processing of side effect:
val res = x match {
case Some(a) => s"Value: $a"
case None => "no value"
}
You need to decide what happens when the option is None. Do you provide a default value?
def unroll(opt: Option[Long]): Long = opt getOrElse -1L // -1 if undefined
unroll(None) // -> -1
You could also throw an exception:
def unroll(opt: Option[Long]): Long = opt.getOrElse(throw
new IllegalArgumentException("The option is expected to be defined at this point")
)
unroll(None) // -> exception
In case, refrain from using null, unless you have very good reasons to use it (opt.orNull).
As has already been mentioned getOrElse is probably what you're looking for in answering your question directly.
Please note also that to convert to an option you can simply:
val myOption = Option(1)
myOption will now be Some(1)
val myOption = Option(null)
myOption will now be None.

How to check to see if a string is a decimal number in Scala

I'm still fairly new to Scala, and I'm discovering new and interesting ways for doing things on an almost daily basis, but they're not always sensible, and sometimes already exist within the language as a construct and I just don't know about them. So, with that preamble, I'm checking to see if a given string is comprised entirely of digits, so I'm doing:
def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)
is this sensible or just needlessly silly? It there a better way? Is it better just to call x.toInt and catch the exception, or is that less idiomatic? Is there a performance benefit/drawback to either?
Try this:
def isAllDigits(x: String) = x forall Character.isDigit
forall takes a function (in this case Character.isDigit) that takes an argument that is of the type of the elements of the collection and returns a Boolean; it returns true if the function returns true for all elements in the collection, and false otherwise.
Do you want to know if the string is an integer? Then .toInt it and catch the exception. Do you instead want to know if the string is all digits? Then ask one of:
s.forall(_.isDigit)
s matches """\d+"""
You also may consider something like this:
import scala.util.control.Exception.allCatch
def isLongNumber(s: String): Boolean = (allCatch opt s.toLong).isDefined
// or
def isDoubleNumber(s: String): Boolean = (allCatch opt s.toDouble).isDefined
You could simply use a regex for this.
val onlyDigitsRegex = "^\\d+$".r
def isAllDigits(x: String) = x match {
case onlyDigitsRegex() => true
case _ => false
}
Or simply
def isAllDigits(x: String) = x.matches("^\\d+$")
And to improve this a little bit, you can use the pimp my library pattern to make it a method on your string:
implicit def AllDigits(x: String) = new { def isAllDigits = x.matches("^\\d+$") }
"12345".isAllDigits // => true
"12345foobar".isAllDigits // => false
Starting Scala 2.13 we can use String::toDoubleOption, to determine whether a String is a decimal number or not:
"324.56".toDoubleOption.isDefined // true
"4.06e3".toDoubleOption.isDefined // true
"9w01.1".toDoubleOption.isDefined // false
Similar option to determine if a String is a simple Int:
"324".toIntOption.isDefined // true
"à32".toIntOption.isDefined // false
"024".toIntOption.isDefined // true
import scala.util.Try
object NumCruncher {
def isShort(aString: String): Boolean = Try(aString.toLong).isSuccess
def isInt(aString: String): Boolean = Try(aString.toInt).isSuccess
def isLong(aString: String): Boolean = Try(aString.toLong).isSuccess
def isDouble(aString: String): Boolean = Try(aString.toDouble).isSuccess
def isFloat(aString: String): Boolean = Try(aString.toFloat).isSuccess
/**
*
* #param x the string to check
* #return true if the parameter passed is a Java primitive number
*/
def isNumber(x: String): Boolean = {
List(isShort(x), isInt(x), isLong(x), isDouble(x), isFloat(x))
.foldLeft(false)(_ || _)
}
}
Try might not performance-wise be the optimal choice, but otherwise it's neat:
scala> import scala.util.Try
scala> Try{ "123x".toInt }
res4: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "123x")
scala> Try{ "123x".toInt }.isSuccess
res5: Boolean = false
#Jesper's answer is spot on.
Do NOT do what I'm suggesting below (explanation follows)
Since you are checking if a given string is numeric (title states you want a decimal), the assumption is that you intend to make a conversion if the forall guard passes.
A simple implicit in scope will save a whopping 9 key strokes ;-)
implicit def str2Double(x: String) = x.toDouble
Why this is dangerous
def takesDouble(x: Double) = x
The compiler will now allow takesDouble("runtime fail") since the implicit tries to convert whatever string you use to Double, with zero guarantee of success, yikes.
implicit conversions then seem better suited to situations where an acceptable default value is supplied on conversion failure (which is not always the case; therefore implicit with caution)
Here is one more:
import scala.util.Try
val doubleConverter: (String => Try[Double]) = (s: String) => Try{ s.map(c => if ((Character.isDigit(c) == true) || (c == '.')) Some(c) else None).flatten.mkString.toDouble }
val d1: Try[Double] = doubleConverter("+ 1234.0%")
val d2: Try[Double] = doubleConverter("+ 1234..0%")
Based on brilliant Jexter's solution, in this piece of code I take care of the NullPointerException using Option:
def isValidPositiveNumber(baseString: Option[String]): Boolean = baseString match {
case Some(code) => !code.isEmpty && (code forall Character.isDigit)
case None => false
}

How to check for null or false in Scala concisely?

In Groovy language, it is very simple to check for null or false like:
groovy code:
def some = getSomething()
if(some) {
// do something with some as it is not null or emtpy
}
In Groovy if some is null or is empty string or is zero number etc. will evaluate to false. What is similar concise method of testing for null or false in Scala?
What is the simple answer to this part of the question assuming some is simply of Java type String?
Also another even better method in groovy is:
def str = some?.toString()
which means if some is not null then the toString method on some would be invoked instead of throwing NPE in case some was null. What is similar in Scala?
What you may be missing is that a function like getSomething in Scala probably wouldn't return null, empty string or zero number. A function that might return a meaningful value or might not would have as its return an Option - it would return Some(meaningfulvalue) or None.
You can then check for this and handle the meaningful value with something like
val some = getSomething()
some match {
case Some(theValue) => doSomethingWith(theValue)
case None => println("Whoops, didn't get anything useful back")
}
So instead of trying to encode the "failure" value in the return value, Scala has specific support for the common "return something meaningful or indicate failure" case.
Having said that, Scala's interoperable with Java, and Java returns nulls from functions all the time. If getSomething is a Java function that returns null, there's a factory object that will make Some or None out of the returned value.
So
val some = Option(getSomething())
some match {
case Some(theValue) => doSomethingWith(theValue)
case None => println("Whoops, didn't get anything useful back")
}
... which is pretty simple, I claim, and won't go NPE on you.
The other answers are doing interesting and idiomatic things, but that may be more than you need right now.
Well, Boolean cannot be null, unless passed as a type parameter. The way to handle null is to convert it into an Option, and then use all the Option stuff. For example:
Option(some) foreach { s => println(s) }
Option(some) getOrElse defaultValue
Since Scala is statically type, a thing can't be "a null or is empty string or is zero number etc". You might pass an Any which can be any of those things, but then you'd have to match on each type to be able to do anything useful with it anyway. If you find yourself in this situation, you most likely are not doing idiomatic Scala.
In Scala, the expressions you described mean that a method called ? is invoked on an object called some. Regularly, objects don't have a method called ?. You can create your own implicit conversion to an object with a ? method which checks for nullness.
implicit def conversion(x: AnyRef) = new {
def ? = x ne null
}
The above will, in essence, convert any object on which you call the method ? into the expression on the right hand side of the method conversion (which does have the ? method). For example, if you do this:
"".?
the compiler will detect that a String object has no ? method, and rewrite it into:
conversion("").?
Illustrated in an interpreter (note that you can omit . when calling methods on objects):
scala> implicit def any2hm(x: AnyRef) = new {
| def ? = x ne null
| }
any2hm: (x: AnyRef)java.lang.Object{def ?: Boolean}
scala> val x: String = "!!"
x: String = "!!"
scala> x ?
res0: Boolean = true
scala> val y: String = null
y: String = null
scala> y ?
res1: Boolean = false
So you could write:
if (some ?) {
// ...
}
Or you could create an implicit conversion into an object with a ? method which invokes the specified method on the object if the argument is not null - do this:
scala> implicit def any2hm[T <: AnyRef](x: T) = new {
| def ?(f: T => Unit) = if (x ne null) f(x)
| }
any2hm: [T <: AnyRef](x: T)java.lang.Object{def ?(f: (T) => Unit): Unit}
scala> x ? { println }
!!
scala> y ? { println }
so that you could then write:
some ? { _.toString }
Building (recursively) on soc's answer, you can pattern match on x in the examples above to refine what ? does depending on the type of x. :D
If you use extempore's null-safe coalescing operator, then you could write your str example as
val str = ?:(some)(_.toString)()
It also allows you to chain without worrying about nulls (thus "coalescing"):
val c = ?:(some)(_.toString)(_.length)()
Of course, this answer only addresses the second part of your question.
You could write some wrapper yourself or use an Option type.
I really wouldn't check for null though. If there is a null somewhere, you should fix it and not build checks around it.
Building on top of axel22's answer:
implicit def any2hm(x: Any) = new {
def ? = x match {
case null => false
case false => false
case 0 => false
case s: String if s.isEmpty => false
case _ => true
}
}
Edit: This seems to either crash the compiler or doesn't work. I'll investigate.
What you ask for is something in the line of Safe Navigation Operator (?.) of Groovy, andand gem of Ruby, or accessor variant of the existential operator (?.) of CoffeeScript. For such cases, I generally use ? method of my RichOption[T], which is defined as follows
class RichOption[T](option: Option[T]) {
def ?[V](f: T => Option[V]): Option[V] = option match {
case Some(v) => f(v)
case _ => None
}
}
implicit def option2RichOption[T](option: Option[T]): RichOption[T] =
new RichOption[T](option)
and used as follows
scala> val xs = None
xs: None.type = None
scala> xs.?(_ => Option("gotcha"))
res1: Option[java.lang.String] = None
scala> val ys = Some(1)
ys: Some[Int] = Some(1)
scala> ys.?(x => Some(x * 2))
res2: Option[Int] = Some(2)
Using pattern matching as suggested in a couple of answers here is a nice approach:
val some = Option(getSomething())
some match {
case Some(theValue) => doSomethingWith(theValue)
case None => println("Whoops, didn't get anything useful back")
}
But, a bit verbose.
I prefer to map an Option in the following way:
Option(getSomething()) map (something -> doSomethingWith(something))
One liner, short, clear.
The reason to that is Option can be viewed as some kind of collection – some special snowflake of a collection that contains either zero elements or exactly one element of a type and as as you can map a List[A] to a List[B], you can map an Option[A] to an Option[B]. This means that if your instance of Option[A] is defined, i.e. it is Some[A], the result is Some[B], otherwise it is None. It's really powerful!