Is there any way to automatically parse a case object from a string, in Scala? Using some built in / automatically generated Scala function?
For example, I have these case objects: (please note that there's a sealed parent class)
abstract sealed class FlagReason
case object Spam extends FlagReason
case object Illegal extends FlagReason
case object CopyrightViolation extends FlagReason
case object Other extends FlagReason
and I'm wondering if there's some automatically generated function that works like:
FlagReason.fromString(value: String): FlagReason
where FlagReason("Spam")
would return the Spam
case object.
If there were, then I need not write my own -- which I've done:
object FlagReason {
def fromString(value: String): FlagReason = value match {
case "Spam" => Spam
case "Illegal" => Illegal
case "CopyrightViolation" => CopyrightViolation
case "Other" => Other
}
}
Background: I'm converting my case objects to strings that I use as radio button values in a html form. I'm converting the selected value back to a case object, when I handle the submitted form.
Related info: This is actually possible with Java enums, see e.g. this StackOverflow question: Lookup enum by string value
((I don't think I'm looking for Scala's Parser Combinators. I suppose that were I to use them I'd still need to define the parsing rules myself, rather than having built in "automatic" string to case object conversion))
A case object is like an object , but just like a case class has more features than a regular class, a case object has more features than a regular object. Its features include: It's serializable. It has a default hashCode implementation. It has an improved toString implementation.
A Scala Case Class is like a regular class, except it is good for modeling immutable data. It also serves useful in pattern matching, such a class has a default apply() method which handles object construction. A scala case class also has all vals, which means they are immutable.
Scala case classes are just regular classes which are immutable by default and decomposable through pattern matching. It uses equal method to compare instance structurally. It does not use new keyword to instantiate object. All the parameters listed in the case class are public and immutable by default. Syntax.
The one of the topmost benefit of Case Class is that Scala Compiler affix a method with the name of the class having identical number of parameters as defined in the class definition, because of that you can create objects of the Case Class even in the absence of the keyword new.
No, no such method is automatically generated. You will have to write your own fromString
method. Note that you can write it more compactly as follows:
object FlagReason {
def fromString(value: String): Option[FlagReason] = {
Vector(Spam, Illegal, CopyRightViolation, Other).find(_.toString == value)
}
}
Alternatively you may consider using scala.Enumeration
which does provide this facility.
object FlagReason extends Enumeration {
val Spam, Illegal, CopyRightViolation, Other = Value
}
Then you can obtain the particular enum value with FlagReason withName "<name>"
, or safely as an Option
with Try(FlagReason withName "<name>").toOption
.
As missingfaktor points out, FlagReason withName "<name>"
should do what you need. But if <name>
is not a valid name, it will throw an exception. So, a slightly safer way to handle this when you are not sure if the name is valid is to use Option[FlagReason]
:
scala> def parse(name: String) = FlagReason.values.find(_.toString == name)
parse: (name: String)Option[FlagReason.Value]
scala> parse("Spam")
res0: Option[FlagReason.Value] = Some(Spam)
scala> parse("NonExisting")
res1: Option[FlagReason.Value] = None
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With