I am searching for the opposite of distinct.
In a list with [ "a", "a", "b", "c", "b", "d" ] I only want to keep "a" and "b" because they appear multiple times.
A solution for this could be the following:
val similarsList = mutableListOf<String>()
list.filter {
if (similars.contains(it))
return@filter true
similars.add(it)
false
}.distinct()
This will remove every element that matches an already contained element before it. In the list object all elements appearing multiple times will be stored after filter. distinct in this case cleans elements that appeared three or more times.
I am searching for an idiomatic way of doing exactly that, the opposite of distinct.
A small improvement to the solution provided by @gil.fernandes can be made by using the API introduced in the Kotlin 1.1 standard library: .groupingBy { ... }. Instead of creating the groups right away, it creates a lazy Grouping, which can then be queried. In particular, we can ask it for .eachCount(), which returns Map<T, Int>:
val l = listOf("a", "a", "b", "c", "b", "d")
val result = l.groupingBy { it }.eachCount().filterValues { it > 1 }.keys
It is a little bit more efficient than using .groupBy { ... }, because it does not store the groups in the lists.
If you want to filter out duplicates (non distinct items) you could try:
fun main(args: Array<String>) {
val l = listOf( "a", "a", "b", "c", "b", "d" )
println(l.groupBy { it }.filter { it.value.size > 1 }.keys)
}
This prints out:
[a, b]
Explanation: l.groupBy { it } produces a grouped map with this content:
{a=[a, a], b=[b, b], c=[c], d=[d]}
Then a filter is applied to this map, filtering by the values (which are lists) with a length superior to 1: filter { it.value.size > 1 }.
Finally the keys are extracted with keys.
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