What is the best way to compare two classes of the...
# getting-started
a
What is the best way to compare two classes of the same type, and copy all the properties of the second one that are different compared to an original? For example, let's say I have 3 string variables stored in said class:
Copy code
class SomeClass {
    var string1: String = "Default"
    var string2: String = "Default"
    var string3: String = "Default"
}
and lets say in the first class,
string1
is "Text,"
string2
, is "Other Text," and in the second class
string1
is "String, " while
string2
is still Default I would want it so that the first string is "String," the second string is "Other Text," and
string3
as "Default"
a
when you say "first class" and "second class", you mean "first instance of SomeClass", and "second instance of SomeClass"? Or do you want to compare 3 different classes? Why do you expect
string2="Other Text"
? Shouldn't it be "Default", because
second.string1 != first.string1
?
a
Yes, I'm referring them as all the same class, but with different properties
If nothing was changed in the first class, and in the second class the first variable was changed, then the output should produce the first variable as whatever the second class was and the rest as the values in the first class
m
putting a "default" value on a string means it has a special meaning within your code. I think it might be better to just use
String?
instead, but regardless. I dont know what you want with the copying over, but you can do:
Copy code
import SomeClass.Companion.DEFAULT

class SomeClass {
    companion object {
        const val DEFAULT = "Default"
    }
    var string1: String = DEFAULT
    var string2: String = DEFAULT
    var string3: String = DEFAULT
}

fun main() {
    val class1 = SomeClass().apply {
        string1 = "Text"
        string2 = "OtherText"
    }
    val class2 = SomeClass().apply {
        string1 = "String"
    }

    val result1 = class2.string1.takeUnless(DEFAULT::equals) ?: class1.string1
    val result2 = class2.string2.takeUnless(DEFAULT::equals) ?: class1.string2
    val result3 = class2.string3.takeUnless(DEFAULT::equals) ?: class1.string3

    println(result1)
    println(result2)
    println(result3)
}
this prints, in order:
Copy code
String
OtherText
Default
if you instead have nullable string with null being the default, you can just do:
Copy code
val result1 = class2.string1 ?: class1.string1
    val result2 = class2.string2 ?: class1.string2
    val result3 = class2.string3 ?: class1.string3
it is ofcourse also possible to use reflection to automatically compare all fields, however, I don't think you can easily check for a default value this way. So If you pretend your defaults are "null" instead:
Copy code
SomeClass::class.memberProperties.map {
    it.name to (it.get(class2) ?: it.get(class1))
}.forEach(::println)
prints
Copy code
(string1, String)
(string2, OtherText)
(string3, null)
a
Alright, thanks!