所以我有Enumeration
:
object MyEnum extends Enumeration {
val a = Value(0, "Valid")
val b = Value(1, "Valid")
val c = Value(2, "Not Valid")
val d = Value(3, "Not Valid")
}
此Enumeration
包含两种类型:Valid
和Not valid
。
是否可以按值选择随机MyEnum
?
例如,我想选择MyEnum
的随机Valid
。
答案 0 :(得分:2)
即使Yuval答案正确并且解决方案可行,也不建议使用Enumeration
编码其他属性。通过使用name
字段将"Valid"
或"Not Valid"
(或任何其他类别)的类型编码为Value
,您正在失去Enumeration
的能力通过String
方法从.withName
重建枚举值实例的类:
// result will be always `a` for "Valid" and `b` for "Not Valid"
// it will throw an NoSuchElementException for any other string
MyEnum.withName(someString)
当你只是误用name
字段来分类你的枚举值实例时,简单地说。如果这不是您的代码中的问题,那么您就是一个幸运的人,但无论如何都要非常准确地记录误用。
Enumeration
旨在表达简单的值,这些值具有索引并且可以具有良好的人类可读名称。这就是它,不多也不少。
经验法则是,当你有一个需要另一个字段的枚举时,最好使用密封的case objects
或case classes
层次结构对其进行建模。这样的事情(只是你特定案例的一个例子):
// Hierarchy is sealed, thus you will get can pattern match with check for exhaustiveness
sealed trait MyEnum {
def id: Int
def name: String
def valid: Boolean
}
// Helper case class, which allows to not define
private case class Value(id: Int, name: String, valid: Boolean) extends MyEnum
object MyEnum {
// Your values
val A: MyEnum = Value(0, "My A", true)
val B: MyEnum = Value(1, "My B", true)
val C: MyEnum = Value(0, "My A", false)
val D: MyEnum = Value(1, "My B", false)
// Re-implementation of methods contained in Enumeration, pick what you need
val values: Seq[MyEnum] = Seq(A, B, C, D)
// You can implement your own semantics, e.g. no Exception rather Option
def withName(name: String): Option[MyEnum] = values.find( _.name == name )
// Methods already for your example
val valids: Seq[MyEnum] = values.filter( _.valid )
// Or with randomization build in to enum
def randomValid: MyEnum = valids(util.Random.nextInt(valids.length))
}
此外,您将获得更多类型安全性:
// More type safety, fn simple does not compile
def fn(value: MyEnum) = value match {
case MyEnum.A => true
}
<console>:14: warning: match may not be exhaustive.
It would fail on the following input: Value(_, _, _)
def fn(value: MyEnum) = value match {
^
fn: (value: MyEnum)Boolean
你的milage可能会有所不同,因为在Scala中编写枚举的可能性几乎是无穷无尽的:)在我的例子中,我只展示了许多可能的实现之一。如果你有很多值,上面提到的方法可能是不切实际的。
要详细了解使用Enumeration
的缺点,请参阅"Scala Enumerations"博文。 请注意文章末尾的解决方案不是银弹,并且模式匹配穷举检查存在问题{/ 1}}。
享受
答案 1 :(得分:0)
这应该做你需要的:
val valids = MyEnum.values.filter { _.toString.equalsIgnoreCase("Valid") }.toSeq
val selected = valids(util.Random.nextInt(valids.length))
println(s"Selected $selected with id: ${selected.id}")
答案 2 :(得分:0)
你可以使用scala Random:
scala.util.Random.shuffle(MyEnum.values.toList).find(_.toString.equalsIgnoreCase("Valid"))
它会返回一个选项