Quiero poder verificar que la colección a contiene exactamente todos los elementos de b , pero una verificación basada en la igualdad no es suficiente; por ejemplo:
data class Person(val name: String, val age: Int) val a = listOf(Person("Alice", 10), Person("Bob", 13)) val b = listOf(Person("Alice", 10), Person("Alice", 10)) fun main() { println(a.containsAll(b)) }verdadero
Si bien esto es técnicamente true , no es el resultado que quiero, porque a solo contiene una Person("Alice", 10) , mientras que b contiene dos de ellos.
El ejemplo anterior debería fallar, mientras que el siguiente debería pasar.
data class Person(val name: String, val age: Int) val a = listOf(Person("Alice", 10), Person("Alice", 10), Person("Bob", 13)) val b = listOf(Person("Alice", 10), Person("Alice", 10)) fun main() { println(a.containsAllExact(b)) }¿Hay alguna forma de hacer esto?
Podría agregar una función de extensión para esto, algo como:
fun List<Person>.containsAllExact(list2: List<Person>): Boolean { val occurences1 = this.groupingBy{ it }.eachCount() val occurences2 = list2.groupingBy{ it }.eachCount() return occurences2.all{ it.value <= occurences1.getOrDefault(it.key, 0) } }Una forma en la que puedo pensar es hacer una copia mutable de a e intentar eliminar todos los elementos de b , luego verifique si todos los elementos de b se pueden eliminar:
println( a.toMutableList().let { aCopy -> b.all(aCopy::remove) } )O como una función de extensión:
fun <T> Iterable<T>.strictlyContainsAll(other: Iterable<T>) = toMutableList().let { copy -> other.all(copy::remove) }Creo que esto lo haría
println(a.containsAll(b) && (a.size - b.size == (ab).size))Editar: no funciona porque también da falsos negativos. por ejemplo con
val a = listOf(Person("Alice", 10), Person("Alice", 10), Person("Bob", 13)) val b = listOf(Person("Alice", 10))