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