scala - iterate over case class data members -


i writing play2.1 application mongodb, , model object bit extensive. when updating entry in db, need compare temp object coming form what's in db, can build update query (and log changes).

i looking way generically take 2 instances , diff of them. iterating on each data member long, hard-coded , error prone (if a.firstname.equalsignorecase(b.firstname)) looking way iterate on data members , compare them horizontally (a map of name -> value do, or list can trust enumerate data members in same order every time).

any ideas?

case class customer(   id: option[bsonobjectid] = some(bsonobjectid.generate),   firstname: string,   middlename: string,   lastname: string,   address: list[address],   phonenumbers: list[phonenumber],   email: string,   creationtime: option[datetime] = some(datetime.now()),   lastupdatetime: option[datetime] = some(datetime.now()) ) 

all 3 solutions below great, still cannot field's name, right? means can log change, not field affected...

expanding on @malte_schwerhoff's answer, potentially create recursive diff method not generated indexes of differences, mapped them new value @ index - or in case of nested product types, map of sub-product differences:

def diff(orig: product, update: product): map[int, any] = {   assert(orig != null && update != null, "both products must non-null")   assert(orig.getclass == update.getclass, "both products must of same class")    val diffs = (ix <- 0 until orig.productarity) yield {     (orig.productelement(ix), update.productelement(ix)) match {       case (s1: string, s2: string) if (!s1.equalsignorecase(s2)) => some((ix -> s2))       case (s1: string, s2: string) => none       case (p1: product, p2: product) if (p1 != p2) => some((ix -> diff(p1, p2)))       case (x, y) if (x != y) => some((ix -> y))       case _ => none     }   }    diffs.flatten.tomap } 

expanding on use cases answer:

case class a(x: int, y: string) case class b(a: a, b: anyref, c: any)  val a1 = a(4, "four") val a2 = a(4, "four") val a3 = a(4, "quatre") val a4 = a(5, "five") val b1 = b(a1, null, 6) val b2 = b(a1, null, 7) val b3 = b(a2, a2, a2) val b4 = b(a4, null, 8)  println(diff(a1, a2)) // map() println(diff(a1, a3)) // map(0 -> 5) println(diff(a1, a4)) // map(0 -> 5, 1 -> five)  println(diff(b1, b2)) // map(2 -> 7) println(diff(b1, b3)) // map(1 -> a(4,four), 2 -> a(4,four)) println(diff(b1, b4)) // map(0 -> map(0 -> 5, 1 -> five), 2 -> 8l 

Comments

Popular posts from this blog

javascript - DIV "hiding" when changing dropdown value -

Does Firefox offer AppleScript support to get URL of windows? -

android - How to install packaged app on Firefox for mobile? -