Skip to content

Instantly share code, notes, and snippets.

@scottashipp
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottashipp/74968563149735fa77e5 to your computer and use it in GitHub Desktop.
Save scottashipp/74968563149735fa77e5 to your computer and use it in GitHub Desktop.
Scala extractor with "collect" example
object MemberType extends Enumeration {
type MemberType = Value
val Free, Trial, Pay, Premium = Value
}
object MemberStatus extends Enumeration {
type MemberStatus = Value
val Active, Inactive, Disabled = Value
}
class DataRecord(val id: Long, val status: MemberStatus.Value, val name: String, val memType: MemberType.Value, val accessKey: String)
//.. envision DataRecord actually having 30+ attributes
trait Member {
val name: String
}
class Free(val name: String) extends Member
object Free {
def unapply(d: DataRecord): Option[Member] = {
if(d.memType == MemberType.Free)
Option(new Free(d.name))
else
None
}
}
class Pay(val name: String) extends Member
object Pay {
def unapply(d: DataRecord): Option[Member] = {
if(d.status == MemberStatus.Active && d.memType == MemberType.Trial || d.memType == MemberType.Pay)
Option(new Pay(d.name))
else
None
}
}
class Premium(val name: String, val accessKey: Option[String]) extends Member
object Premium {
def unapply(d: DataRecord): Option[Member] = {
if(d.status == MemberStatus.Active && d.memType == MemberType.Premium)
Option(new Premium(d.name, Option(d.accessKey)))
else
None
}
}
val pierre = new DataRecord(1, MemberStatus.Inactive, "Pierre", MemberType.Pay, "1111")
val joanne = new DataRecord(2, MemberStatus.Inactive, "Joannne", MemberType.Free, "")
val du = new DataRecord(3, MemberStatus.Active, "Du", MemberType.Premium, "3333")
val petra = new DataRecord(4, MemberStatus.Disabled, "Petra", MemberType.Premium, "4444")
val chin = new DataRecord(5, MemberStatus.Active, "Chin", MemberType.Trial, "5555")
val carlos = new DataRecord(6, MemberStatus.Active, "Carlos", MemberType.Pay, "6666")
val tran = new DataRecord(7, MemberStatus.Active, "Tran", MemberType.Pay, "7777")
val alva = new DataRecord(8, MemberStatus.Active, "Alva", MemberType.Premium, "8888")
val nan = new DataRecord(9, MemberStatus.Active, "Nan", MemberType.Free, "")
val steve = new DataRecord(10, MemberStatus.Active, "Steve", MemberType.Free, "101010")
val allData = List(pierre, joanne, du, petra, chin, carlos, tran, alva, nan, steve)
def getMembers(allData: List[DataRecord], whichType: { def unapply(d: DataRecord): Option[Member] }): List[Member] = allData collect { case whichType(n) => n }
def premiumMembers = getMembers(allData, Premium)
def payMembers = getMembers(allData, Pay)
def greetMembers(memList: List[Member], greeting: String) = for(m <- memList) { println(String.format(greeting, m.name)) }
def premiumGreeting = "Hello, %s! Premium members get the best experience! "
def payGreeting = "Hello, %s! Become a premium member and upgrade your experience!"
greetMembers(premiumMembers, premiumGreeting)
greetMembers(payMembers, payGreeting)
//An alternative to the above approach is to pass the class to the method
def makeMember(allData:List[DataRecord], typeOfMemberToMake: Class[_]) = {
//You must create stable identifiers to match on class
//See http://stackoverflow.com/questions/7157143/how-can-i-match-classes-in-a-scala-match-statement
val ClassFree = classOf[Free]
val ClassPay = classOf[Pay]
val ClassPremium = classOf[Premium]
typeOfMemberToMake match {
case ClassFree => { allData collect { case Free(n) => n } }
case ClassPay => { allData collect { case Pay(n) => n } }
case ClassPremium => { allData collect { case Premium(n) => n } }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment