Skip to content

Instantly share code, notes, and snippets.

@coderunner
Last active December 16, 2015 08:58
Show Gist options
  • Select an option

  • Save coderunner/5409233 to your computer and use it in GitHub Desktop.

Select an option

Save coderunner/5409233 to your computer and use it in GitHub Desktop.
object CaseToList extends App {
trait Collapsable {
// OPTION 1
// Use reflection on the fields using the known public method of the property to access its value.
// Can be incorrect if the case class defines attributes not to be added to the list.
// Here I use the property name in the returned tuple list.
def toCollapsedList1: Seq[Any] = {
val list = for {
f <- this.getClass.getDeclaredFields
} yield (f.getName -> this.getClass.getDeclaredMethod(f.getName).invoke(this))
list.filter(_._2 != None).map {
case (id, Some(v)) => (id -> v)
case (id, x) => (id -> x)
}
}
// OPTION 2
// Define an abstract method that convert the desired properties to a List
def toList: List[Any]
// Then use a generic method that filters out None and extract values from Some and let other types go by unchanged.
// Here I zip with numbers to have tuple of the form (1 -> value).
def toCollapsedList2: Seq[Any] = {
val values = toList
for (pair <- (1 to values.size).zip(values) if pair._2 != None) yield pair match {
case (id, Some(v)) => (id -> v)
case (id, x) => (id -> x)
}
}
}
case class Query(c1: String, c2: Option[String], c3: Option[Double]) extends Collapsable {
def toList = c1 :: c2 :: c3 :: Nil
}
val q1 = Query("allo", None, Some(3.0))
println(q1.toCollapsedList1.mkString)
println(q1.toCollapsedList2.mkString)
}
@coderunner
Copy link
Author

toList could be a lazy val too.

As for the reflection option, you could load fields and methods in lazy vals to limit the cost of using reflection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment