0

I saw the following solution for an enum somewhere

object Day {
  val values = new ArrayBuffer[Day]
  case class Day(name:String) {
    values += this
  }
  val MONDAY = new Day("monday")
  val TUESDAY = new Day("tuesday")
}

This demonstrates what I am trying to go for EXCEPT there is a var hidden in the ArrayBuffer....that is kind of icky.

What I really want is a val lookupTable = Map() where when a request comes in, I can lookup "monday" and translate it to my enum MONDAY and use the enum throughout the software. How is this typically done. I saw sealed traits but didn't see a way to automatically make sure that when someone adds a class that extends it, that it would automatically be added to the lookup table. Is there a way to create a scala enum with lookup table?

A scala Enumeration seems close as it has a values() method but I don't see how to pass in the strings representing the days which is what we receive from our user and then translate that into an enum.

thanks, Dean

Dean Hiller
  • 19,235
  • 25
  • 129
  • 212
  • 2
    Is not `withName` method what you want? http://www.scala-lang.org/api/current/index.html#scala.Enumeration – Krever Oct 21 '14 at 18:39
  • 1
    Will you be creating new versions of the `Day` type at runtime or is this going to be a kind of enum? If an enum, have you seen [this question about macro-based sealed trait enums](http://stackoverflow.com/q/12078366/135978) or [this one](http://stackoverflow.com/q/20089920/135978)? – Sean Vieira Oct 21 '14 at 21:32
  • `withName` scans the values of the enumeration looking for a match, so there's benefit to creating a lookup table. – cbmanica Aug 24 '21 at 15:08

2 Answers2

3

Updated to show you how to rename an enum val, add additional constructor parameters, and how to add additional methods to your enum.

object Currency extends Enumeration {

  sealed case class CurrencyVal(name: String, value: Int) extends Val(name) {
    def *(n: Int): Int = n * value
  }

  val PENNY   = CurrencyVal("penny", 1)
  val NICKLE  = CurrencyVal("nickle", 5)
  val DIME    = CurrencyVal("dime", 10)
  val QUARTER = CurrencyVal("quarter", 25)

  override def withName(name: String): CurrencyVal = {
    super.withName(name).asInstanceOf[CurrencyVal]
  }
}

If you don't override withName then you get back a Currency.Value and not a Currency.CurrencyVal.

Nate
  • 2,205
  • 17
  • 21
  • I more want a code to enum mapping. In that case, it would break if someone renamed Mon to Mon2(unlikely in this weekday case but could happen in other cases where you wanted more clarity around a name like Monday instead of Mon). Also, the enums contain multiple params sometimes like integer code, toString version and perhaps one more thing sometimes. – Dean Hiller Oct 21 '14 at 20:04
0

I saw sealed traits but didn't see a way to automatically make sure that when someone adds a class that extends it, that it would automatically be added to the lookup table. Is there a way to create a scala enum with lookup table

I made a small lib here that might help, called Enumeratum. Its usage is as follows:

import enumeratum._

// entryName is for serdes, customise it as you'd like
sealed abstract class Day(val entryName: String) extends EnumEntry

case object Day extends Enum[Day] {

   // This will add Day entries declared below into a map at compile time, automagically
  val values = findValues

  case object MONDAY extends Day("monday")
  case object TUESDAY extends Day("tuesday")
  // etc
}

Day.withName("monday") // => returns MONDAY
lloydmeta
  • 1,289
  • 1
  • 15
  • 25