问题
I've two classes with a few attributes that have the same names, for example:
case class Rect(x: Int, y: Int)
case class Squa(x: Int, y: Int)
To compare it I do:
val r = new Rect(2, 2)
val s = new Squa(2, 2)
r.x == s.x && r.y == x.y
If I have "N" attributes I have to compare one by one, is there a way to compare all attributes at once since they have the same name? I've tried:
r.asInstanceOf[Squa] eq s
But this gives me the error:
class Rect cannot be cast to class Squa (Rect and Squa are in unnamed module of loader scala.reflect.internal.util.ScalaClassLoader$URLClassLoader @3b81a1bc)
The running example: https://repl.it/join/eegmixii-rafa_acioly
回答1:
You can use productIterator. For example you can do:
r.productIterator.sameElements(s.productIterator)
Code run can be found at Scastie
Another option you have is to share a trait between the 2. Let's define:
trait Base extends Ordered[Base] {
val x: Int
val y: Int
override def compare(that: Base): Int = {
if (x != that.x) {
x - that.x
} else {
y - that.y
}
}
}
Then we can test it with:
println("Rect(2,2).compareTo(Squa(2,2)): " + Rect(2,2).compareTo(Squa(2,2))) // 0
println("Rect(2,2) > Squa(2,2) " + (Rect(2,2) > Squa(2,2))) // false
println("Rect(2,2) >= Squa(2,2) " + (Rect(2,2) >= Squa(2,2))) // true
println("Rect(3,2) >= Squa(2,2) " + (Rect(3,2) >= Squa(2,2))) // true
println("Rect(3,2) >= Squa(2,3) " + (Rect(3,2) >= Squa(2,3))) // true
println("Rect(2,3) >= Squa(3,2) " + (Rect(2,3) >= Squa(3,2))) // false
Code run can be found at Scastie.
来源:https://stackoverflow.com/questions/64573743/how-to-compare-attribute-values-from-different-classes