4

I have a data class of Worker,

data class Worker(val id: Int, val name:String, val gender :String, val age :Int, val tel:String,val email:String)

and a list of workers

List<Worker> = listOf(workerA, workerB)

I want to write a function to update the data of Worker, e.g.:

updateWorkerData(1, age, 28)

//'type' refer to name, gender, age ..
//'value' refer AA, Female, 27 ..
fun updateWorkerData(id: Int, type: Any, value: Any) {
  val workers = getListOfWorker()
  workers.forEach {
  if (it.id == id) {
   //here is where I stuck    
  }    
}
}

I'm stuck on how to refer the type to the value in Data class Worker. Need some guide on how to update the Worker's data. Thanks.

3 Answers 3

9

I would prefer to use immutability instead of using mutable fields for a data class.

A simple solution is the following:

fun List<Worker>.updateWorkerDataAge(id: Int, age: Int): List<Worker> =
        this.map { worker -> if (worker.id == id) worker.copy(age = age) else worker }

and you can use it:

val newWorkerList = workerList.updateWorkerDataAge(2, 99)
Sign up to request clarification or add additional context in comments.

1 Comment

Is this working? Its not working for me
5

Your data class should have mutable properties, so that they can be changed:

data class Worker(val id: Int, var name: String, var gender: String, var age: Int, var tel: String, var email: String)

Then you can pass out the KProperty to the function that can change that propety:

fun <T> updateWorkerData(id: Int, property: KMutableProperty1<Worker, T>, value: T) {
    val workers = getListOfWorker()
    workers.forEach {
        if (it.id == id) {
            property.set(it, value)
        }
    }
}

updateWorkerData(1, Worker::age, 28)

1 Comment

It works although I can't truly understand! Anyway, it shows the error of :"Kotlin reflection is not available" when implementing your answer. The error gone after I added: implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" into gradle. Thanks!
1

Animesh's answer is correct, I just wanted to point out that it may be simpler to use a Map of Workers (where the key is the worker ID), and just edit the workers directly, rather than doing clever (and difficult to understand) things with reflection:

val workers: Map<Int, Worker> = listOf(
    Worker(1, "a", "a", 1, "a", "a"),
    Worker(2, "b", "b", 2, "b", "b"),
    Worker(3, "c", "c", 3, "c", "c"),
).map { it.id to it }.toMap()

// Worker 1 changes name
workers.getValue(1).name = "Slartibartfast"

// Worker 2 gets older
workers.getValue(2).age += 1

// Worker 3 changes email
workers.getValue(3).email = "[email protected]"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.