Reputation: 8281
I need to group some values of an Enumeration
.
Here is the code :
object PostType extends Enumeration {
// Documents
val BOOKMARK = Value("bookmark")
val FILE = Value("file")
val NOTE = Value("note")
val WIKIDOC = Value("wikidoc")
…
}
object PostTypes {
type PostTypes = List[PostType.Value]
val DOCUMENTS : PostTypes = List(PostType.BOOKMARK, PostType.FILE, PostType.NOTE, PostType.WIKIDOC)
val QUESTIONS : PostTypes = List(PostType.QUESTION, PostType.QUICKPOLL, PostType.SURVEY)
val EVENT : PostTypes = List(PostType.EVENT)
…
val ALL : PostTypes = PostType.values.toList
}
Is there a better way ?
Here are the cons that I see : PostType.Value
and PostTypes.PostTypes
in client code !
[update] improve code with the help of both answers
object PostType extends Enumeration {
// Documents
val Bookmark = Value("bookmark")
val File = Value("file")
val Note = Value("note")
val Wikidoc = Value("wikidoc")
…
}
object PostTypes {
import PostType._
implicit def toList(pt: Value) = List(pt)
type PostTypes = List[Value]
val Documents = List(Bookmark, File, Note, Wikidoc)
val Questions = List(Question, Quickpoll, Survey)
val All = values.toList
}
[update 2] Another bunch of improvements
object PostType extends Enumeration {
type PostType = Value
type PostTypes = List[Value]
implicit def toList(pt: Value) = List(pt)
// Documents
val Bookmark = Value(1, "bookmark")
val File = Value(2, "file")
val Note = Value(3, "note")
val Wikidoc = Value(12, "wikidoc")
// Declare after Val to avoid runtime error
val Documents = List(Bookmark, File, Note, Wikidoc)
val Questions = List(Question, Quickpoll, Survey)
val All = values.toList.sorted
}
Upvotes: 1
Views: 2179
Reputation: 8281
Here is the final code, with the help of other answers.
Just need to import PostType._
in client code.
object PostType extends Enumeration {
type PostType = Value
type PostTypes = List[Value]
implicit def toList(pt: Value) = List(pt)
// Documents
val Bookmark = Value(1, "bookmark")
val File = Value(2, "file")
val Note = Value(3, "note")
val Wikidoc = Value(12, "wikidoc")
// Declare after Val to avoid runtime error
val Documents = List(Bookmark, File, Note, Wikidoc)
val Questions = List(Question, Quickpoll, Survey)
val All = values.toList.sorted
}
Upvotes: 0
Reputation: 910
Below is an approach that does not use enumerations, but hopefully achieves your aims. The example shows how to instantiate PostType
from a String
instance. If the String
does not match then a MatchError
is thrown.
package rando
object PostType {
val all = Document.all ++ Question.all
def fromString(s: String): PostType = Document.fromString.orElse(Question.fromString)(s)
}
sealed trait PostType
object Document {
val all = Set(Bookmark, File, Note, Wikidoc)
val fromString: PartialFunction[String, Document] = {
case "bookmark" => Bookmark
case "file" => File
case "note" => Note
case "wikidoc" => Wikidoc
}
}
sealed trait Document extends PostType
case object Bookmark extends Document
case object File extends Document
case object Note extends Document
case object Wikidoc extends Document
object Question {
val all = Set(SlowPoll, QuickPoll, Survey)
val fromString: PartialFunction[String, Question] = {
case "slowpoll" => SlowPoll
case "quickpoll" => QuickPoll
case "survey" => Survey
}
}
sealed trait Question extends PostType
case object SlowPoll extends Question
case object QuickPoll extends Question
case object Survey extends Question
object Example extends App {
println(PostType.fromString("bookmark").getClass)
}
Upvotes: 3
Reputation: 16422
I think it's as good as it gets unless you want to use alternative Enumeration implementation (see my answer here) or just use some constants.
The only thing I could suggest is to define a type alias type PostType = Value
and use it instead of Value
. I'm sure you know that by importing <package>.PostType._
you won't have to prefix your enum values with PostType
anymore.
Finally PostTypes
seems a little bit like overkill and it's easy to confuse it with PostType
when reading. These are just minor things though. I use the same approach as you do and I'm not aware of anything better.
Upvotes: 2