I'm new to Scala, so be nice please. You'll have to excuse me if I'm missing something obvious.
I'm trying to create an enum like structure to represent the days of the week in Scala.
I want a method that accepts a string that can either be the numbers 1 through 7, the full name of the day, or a three letter abbreviation, with any capitalisation, and returns the correct day. Ideally I want to be able to retrieve the correct day simply by writing DayOfWeek(_)
, which as far as I understand things means this method needs to be apply
. The individual values also have to be subclasses (or mix in) a trait called CalendarField
, which at the moment defines no methods or members.
This is my current attempt:
object DayOfWeek extends Enumeration with CalendarField {
val Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday = Value
def apply(v:String) = {
v.toUpperCase match {
case Int(x) => x match {
case 1 => Sunday
case 2 => Monday
case 3 => Tuesday
case 4 => Wednesday
case 5 => Thursday
case 6 => Friday
case 7 => Saturday
case _ => throw new IllegalArgumentException("Invalid value for day of week: " + v)
}
case "SUN" | "SUNDAY" => Sunday
case "MON" | "MONDAY" => Monday
case "TUE" | "TUEDAY" => Tuesday
case "WED" | "WEDNESDAY" => Wednesday
case "THU" | "THURSDAY" => Thursday
case "FRI" | "FRIDAY" => Friday
case "SAT" | "SATURDAY" => Saturday
case _ => throw new IllegalArgumentException("Invalid value for day of week: " + v)
}
}
}
object Int {
def unapply(s : String) : Option[Int] = try {
Some(s.toInt)
} catch {
case _ : java.lang.NumberFormatException => None
}
}
This fails on a few points:
CalendarField
- they are simply Value
s.apply
method but DayOfWeek(_)
doesn't work - my (vague) guess this is because it expects to call a constructor and DayOfWeek
is an object, not a class? Or is it because Enumeration(s:String) is already used? Is there a way round this?Any suggestions on how to get round these problems, or neater solutions, would be greatly appreciated. Thanks.
String[] days = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; Display the day name. The following is the final example.
In Scala, there is no enum keyword unlike Java or C. Scala provides an Enumeration class which we can extend in order to create our enumerations. Every Enumeration constant represents an object of type Enumeration. Enumeration values are defined as val members of the evaluation.
We can an enumeration inside a class. But, we cannot define an enum inside a method. If you try to do so it generates a compile time error saying “enum types must not be local”.
Enums are used when we know all possible values at compile-time, such as choices on a menu, rounding modes, command-line flags, etc. It is not necessary that the set of constants in an enum type stay fixed for all time. In Java (from 1.5), enums are represented using enum data type.
I'd probably implement something like this:
sealed trait DayOfWeek
case object Monday extends DayOfWeek
case object Tuesday extends DayOfWeek
// etc.
object DayOfWeek {
def unapply(s: String): Option[DayOfWeek] = s.toUpperCase match {
case Int(x) => x match {
case 1 => Some(Sunday)
// ...
case _ => None
}
case "SUN" | "SUNDAY" => Some(Sunday)
// ...
case _ => None
}
def apply(s: String): DayOfWeek = s match {
case DayOfWeek(d) => d
case _ => throw new IllegalArgumentException(
"Invalid value for day of week: " + s)
}
}
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