Scala 按值选择随机枚举

Scala 按值选择随机枚举,scala,enumeration,Scala,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") } 此枚举包含两种类型:有效和无效。 是否可以按值选择randomMyEnum 例如,我想选择一个随机的MyEnum,它是有效的这应该满足您的需要: val vali

所以我有一个
枚举

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")
}
枚举
包含两种类型:
有效
无效
。 是否可以按值选择random
MyEnum


例如,我想选择一个随机的
MyEnum
,它是
有效的

这应该满足您的需要:

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}")

您可以使用scala Random:

scala.util.Random.shuffle(MyEnum.values.toList).find(_.toString.equalsIgnoreCase("Valid"))

即使Yuval答案正确且解决方案有效,它也会返回一个选项

,不建议使用
枚举
编码其他属性。通过使用
名称
字段将
值的类型编码为
有效的
无效的
(或任何其他分类),您失去了
枚举
类通过
字符串
重建枚举值实例的内置功能。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
字段对枚举值实例进行分类时。如果这不是代码中的一个问题,那么您就是一个幸运的家伙,但无论如何,请非常准确地记录误用情况

枚举
旨在表示简单的值,这些值具有索引,并且可以具有良好的人类可读名称。就这样,不多不少

经验法则是,当您有一个需要另一个字段的枚举时,最好使用
案例对象的密封层次结构
案例类
进行建模。类似的情况(只是您的特定案例的一个示例):

此外,您将获得更多类型安全性:

// 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
//更多类型安全性,fn simple不编译
def fn(值:MyEnum)=值匹配{
case MyEnum.A=>true
}
:14:警告:匹配可能不完整。
它将在以下输入上失败:值(,,)
def fn(值:MyEnum)=值匹配{
^
fn:(值:MyEnum)布尔值
您的想法可能会有所不同,因为在Scala中编写枚举的可能性几乎是无穷无尽的:)在我的示例中,我只展示了许多可能实现中的一种。如果您有许多值,上述方法可能是不切实际的

要了解有关使用
枚举的缺点的更多信息,请参阅博文。请注意,文章末尾的解决方案并非万能的,并且与
枚举
一样,在模式匹配穷尽性检查方面存在问题。

享受

// 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