Home > Enterprise >  How to optimize code to not using `.compute` and without using `!!` in Kotlin
How to optimize code to not using `.compute` and without using `!!` in Kotlin

Time:03-25

I have following code:

val resultMap = mutableMapOf<String, MutableMap<String, Int>>()
val counter = mutableMapOf<String, Int>() //Meta data

val keywordSearch = keywords.map { it to """(?i)\b($it)\b""".toRegex() }
        
        keywordSearch.forEach { (keywordString,keywordRegex) ->
            if (keywordRegex.containsMatchIn(jobAd.toString())) {
                counter.putIfAbsent(keywordString, 0)
                counter.compute(keywordString) { _, v -> v!!   1 }
                resultMap[weekNumber]!!.compute(keywordString) { _, v -> v!!   1 }
            }
        }

Is there anyway to optimize this code by not using !! inside the counter function -> { _, v -> v!! 1 } for counter and resultmap

CodePudding user response:

Id use the elvis operator ?:

if (keywordRegex.containsMatchIn(jobAd.toString())) {              
  counter.compute(keywordString) { _, v -> (v ?: 0)   1} 
  resultMap[weekNumber]!!.compute(keywordString) { _, v -> v!!   1 }
}

the elvis operator uses v when v not null, otherwise it uses the 0 in this case.

CodePudding user response:

Usually this behaviour is best achieved using merge rather than putIfAbsent and compute:

if (keywordRegex.containsMatchIn(jobAd.toString())) {              
  counter.merge(keywordString, 1, Int::plus) 
  resultMap[weekNumber]!!.merge(keywordString, 1, Int::plus)
}

If the key wasn't already in the map, it sets the value to 1.

If the key was already in the map, it combines the previous value with the new value (1) using the given merge function, here Int::plus, which is a short-hand for { old, new -> old new }.

Also, instead of resultMap[weekNumber]!! you can use resultMap.getValue(weekNumber) which will fail with a better error message if the key is absent.

CodePudding user response:

Might be nice to create a separate extension function for this specific case so your logic code is easier to read.

fun <K> MutableMap<K, Int>.incrementValue(key: K): Int {
    return (getOrDefault(key, 0)   1).also {
        this[key] = it
    }
}
if (keywordRegex.containsMatchIn(jobAd.toString())) {              
  counter.incrementValue(keywordString) 
  resultMap[weekNumber]!!.incrementValue(keywordString)
}
  • Related