Ce face Iterable.groupingBy
groupingBy { ... } nu calculează nimic singur: întoarce un obiect Grouping, care ține minte colecția și funcția-cheie. Pe el apelezi o operație care se face pe fiecare grupă: eachCount(), fold, reduce sau aggregate.
eachCount() întoarce un Map<K, Int>: de câte ori apare fiecare cheie. Este modul obișnuit de a număra frecvențe (cuvinte, voturi, note). Spre deosebire de groupBy, nu se creează liste cu elementele.
Parametri
| Parametru | Descriere |
|---|---|
cheie |
Funcția care dă cheia (grupa) fiecărui element. |
Ce returnează
groupingBy: un Grouping<T, K>. eachCount: un Map<K, Int> cu numărul de elemente pe cheie.
Exemple
Exemplul 1: Numărarea voturilor
Cheia este chiar votul (it). Cheile apar în ordinea primei întâlniri.
fun main() {
val voturi = listOf("Ana", "Ion", "Ana", "Maria", "Ana", "Ion")
val rezultat = voturi.groupingBy { it }.eachCount()
println(rezultat)
val castigator = rezultat.maxBy { it.value }
println("Câștigă ${castigator.key} cu ${castigator.value} voturi")
}
Rezultat
{Ana=3, Ion=2, Maria=1}
Câștigă Ana cu 3 voturi
Exemplul 2: Frecvența literelor într-un cuvânt
Un String se poate parcurge ca o colecție de caractere, deci are și el groupingBy.
fun main() {
val cuvant = "abracadabra"
println(cuvant.groupingBy { it }.eachCount())
}
Rezultat
{a=5, b=2, r=2, c=1, d=1}
Exemplul 3: Total pe categorie cu fold
Pe un Grouping putem face și fold: pentru fiecare categorie pornim de la 0 și adunăm sumele cheltuite.
data class Cheltuiala(val categorie: String, val lei: Int)
fun main() {
val luna = listOf(
Cheltuiala("mâncare", 120), Cheltuiala("transport", 40),
Cheltuiala("mâncare", 85), Cheltuiala("distracție", 60), Cheltuiala("transport", 25),
)
val totaluri = luna.groupingBy { it.categorie }.fold(0) { acc, c -> acc + c.lei }
println(totaluri)
}
Rezultat
{mâncare=205, transport=65, distracție=60}
Greșeli frecvente
- Afișezi direct rezultatul lui
groupingBy: vezi doar numele unui obiect intern. Trebuie apelată o operație, de exemplueachCount(). - Scrii
groupBy { it }.mapValues { it.value.size }: merge, dar creează liste inutile.groupingBy { it }.eachCount()numără direct.
Comenzi înrudite
Iterable.groupBy: Împarte elementele în grupe după o cheie și întoarce un map: cheie → lista elementelor din acea grupă.Iterable.count: Numără elementele colecției sau doar pe cele care îndeplinesc o condiție.Iterable.fold: Pornește de la o valoare inițială și o combină pe rând cu fiecare element, întorcând rezultatul final.Map.maxByOrNull: Găsește intrarea (cheie și valoare) pentru care funcția dată are valoarea maximă; null dacă map-ul e gol.