I am writing a function that iterates through a collection and finds the most common items occurring in it.
Here is what I have so far to get the values and add the number of times they appear in the collection. I'm putting the value into a map as a key and the number of times it appears as its value.
fun mostCommon(input: Collection<Int>): Set<Int> {
var newMap: MutableMap<Int, Int> = HashMap()
for (item in input) {
if (newMap.containsKey(item)) {
//TODO: add 1 to value if key is found
} else {
newMap.put(item, 1)
}
}
return emptySet()
}
I am having trouble finding a way to add 1 to its value if the key already exists.
I tried doing this:
newMap[item] +=1
But I get an error about plusAssign(1) not being allowed on Nullable receiver.
As you already noticed, the error was related to nullability-handling. I'd suggest a more functional approach without explicit looping but simple grouping:
val numbersByElement = input.groupingBy { it }.eachCount()
//gives something like this {1=3, 2=5, 3=4, 5=2, 4=1}
The result is a Map with the elements from input
as its keys and the number of occurrences of the elements as the corresponding values.
You can now find the most common element with maxBy
:
numbersByElement.maxBy { it.value }?.key // gives an Int?
elegant nullsafe solution with Kotlin-1.4 preview
@Test
fun testFindOutMostCommonStringInList() {
val mostCommon = findMostCommonInList(listOf("Foo", "Boo", null, "Foo", "Hello"))
assertEquals("Foo", mostCommon)
}
@Test
fun testFindOutMostCommonIntInList() {
val mostCommon = findMostCommonInList(listOf(1, 2, null, 3, 4, 5, 1))
assertEquals(1, mostCommon)
}
private fun <T>findMostCommonInList(list : List<T>) : T? {
return list
.groupBy { it }
.maxByOrNull { it.value.size }
?.key
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With