YouTing Liu
YouTing Liu

Reputation: 71

Kotlin, How to use the collection function to simplify this code

I am using Kotlin for a project, I write this code can complete the requirement:

val rewards = ArrayList<Map<String, Int>>()
rangeExams
  .forEach { examAnswer ->
    var reward = hashMapOf("Score" to examAnswer.answerScore)
    var questionIds = examAnswer
      .answers
      .map { it.id }

    reward.put("NewQuestion", questionIds.size)
    rewards.add(reward)
  }

"rangeExams" is a list of collection.
I would like to combinate Kotlin Functions of Collection, to put elements of rangeExams into a map and put this map to a new list,
how can I simplify this code by Kotlin ?

ExamAnswer is a pojo:

class ExamAnswer (val id: String, val answerScore: Int, val answers:List<Answer>) 

Thank you for your reply

Upvotes: 0

Views: 867

Answers (2)

guenhter
guenhter

Reputation: 12167

There is a little potential to simplify this.

  • Firstly, I would suggest a more functional approach, which could turn the mutable list rewards into an immutable one.
  • Secondly, infer the creation of the hash-map reward with the put into one line. You than can use the also the immutable version of the map, instead of the mutable one created by hashMapOf (if you need mutability, than you can just keep hashMapOf).
  • thirdly, you just use the questionIds to the the size. For that, you don't have to map anything, just call examAnswer.ansers.size. This short call can be inferred as well
  • fourthly, you can use it instead of explicitly name the param examAnswer because this block is now quite short anyway

This would lead to this code:

val rewards = rangeExams.map { 
        mapOf("Score" to it.answerScore,
              "NewQuestion" to it.answers.size)
    }

Upvotes: 2

hotkey
hotkey

Reputation: 147901

Since you add an item to the rewards for each element of rangeExams, the .forEach { ... } call can be transformed to .map { ... }.

Also, you only use the result of examAnswer.answers.map { it.id } to get its size, so you can remove .map { it.id } and use the size of the original collection.

If you don't need to mutate the maps afterwards, you can replace hashMapOf(...) with mapOf(...).

val rewards = rangeExams.map { 
    mapOf(
        "Score" to it.answerScore,
        "NewQuestion" to it.answers.size)
}

If you need to mutate the rewards list after it's created, add .toMutableList() in the end.

Upvotes: 3

Related Questions