Home > Software design >  Kotlin - Compare values between common fields of two classes
Kotlin - Compare values between common fields of two classes

Time:11-30

I have two classes that share almost all the same properties.

data class UserDetailsDTO( username: String?, id: UUID, lastName: String? ..)
data class UserDetailsInput( username: String?, id: UUID, lastName: String?..)

And I have two variables of the same classes, with populated properties.

 val result = method that returns type UserDetailsDTO
 val update = UserDetailsInput type

I need to do this:

compare update to result, keep only the fields in update that are different from result and not null.

How can I achieve that ? I'd appreciate any guidance.

CodePudding user response:

You can create an utility method witch take them both and return a UserDetailsDTO with only the diff

(I never did kotlin but i think it's something like that )

Class TestDTO(){
    
    public String name;
    
    public  Int age;
    
}

Class TestInput(){
    
    public String name;
    
    public  Int age;
    
}


fun TestDiff(testDTO: TestDTO,testInput : TestInput ){
    
    finalDTO = new TestDTO();
    
    if(testInput.name != null && testInput.name != testDTO.name){
       finalDTO.name =  testInput.name;
    }
    
    if(testInput.age != null && testInput.age != testDTO.age){
        finalDTO.age =  testInput.age;
    }
    
    return finalDTO;
}

CodePudding user response:

You can create an extention function like this:

 fun UserDetailsInput.uniqueValue(UserDetailsDTO: UserDetailsInput) {
            id = if (id != UserDetailsDTO.id) UserDetailsDTO.id else id
            username = if (username != UserDetailsDTO.username) UserDetailsDTO.username else username
            lastName = if (lastName != UserDetailsDTO.lastName) UserDetailsDTO.lastName else lastName
        }

CodePudding user response:

Not very elegant. Uses reflection to check which field of UserDetailsInput exists also in the target class UserDetailsDTO:

import java.util.*
import kotlin.reflect.full.memberProperties

data class UserDetailsDTO(
  val username: String?,
  val id: UUID,
  val lastName: String?
)

data class UserDetailsInput(
  val username: String?,
  val id: UUID,
  val lastName: String?,
  val firstName: String?
)

val result = UserDetailsDTO("User 1", UUID.randomUUID(), "Abc")
val input = UserDetailsInput("User 1", result.id, null, "Super")

val mapOfDifferenValues = mutableMapOf<String, Any?>()

val propsInResult = UserDetailsDTO::class.memberProperties
val propsInInput = UserDetailsInput::class.memberProperties

for (propInInput in propsInInput) {
  // Value from Input
  val valueFromInput = propInInput.get(input)
  // Check if it is not null
  if (valueFromInput != null) {
    // Check if a field with same name exists in 'result' class
    if (propInInput.name in propsInResult.map { it.name }) {
      // A field with same name exists in result class, so check if it has the same value
      if (valueFromInput != propsInResult.first { it.name == propInInput.name }.get(result)) {
        // It does not have the same value, so add it to the map
        mapOfDifferenValues[propInInput.name] = valueFromInput
      }
    } else {
      // There is no field with the same name in 'result' class, so add it to the map
      mapOfDifferenValues[propInInput.name] = valueFromInput
    }
  }
}

println(mapOfDifferenValues)
  • Related