How do I group and count elements using groupBy and count in Kotlin?

In Kotlin, you can group elements with groupBy, then count how many items are in each group.

Basic example

val words = listOf("apple", "banana", "apricot", "blueberry", "avocado")

val countsByFirstLetter = words
    .groupBy { it.first() }
    .mapValues { (_, words) -> words.count() }

println(countsByFirstLetter)

Output:

{a=3, b=2}

Here:

  • groupBy { it.first() } groups words by their first letter.
  • mapValues { it.value.count() } converts each grouped list into its size/count.

You can also write it as:

val countsByFirstLetter = words
    .groupBy { it.first() }
    .mapValues { it.value.size }

Counting objects by a property

data class Person(val name: String, val city: String)

val people = listOf(
    Person("Alice", "London"),
    Person("Bob", "Paris"),
    Person("Charlie", "London"),
    Person("Diana", "Paris"),
    Person("Eve", "Berlin")
)

val peopleByCity = people
    .groupBy { it.city }
    .mapValues { it.value.count() }

println(peopleByCity)

Output:

{London=2, Paris=2, Berlin=1}

More efficient option: groupingBy + eachCount

If you only need counts, prefer:

val countsByFirstLetter = words
    .groupingBy { it.first() }
    .eachCount()

This avoids creating intermediate lists for every group.

println(countsByFirstLetter)
// {a=3, b=2}

So the common choices are:

items.groupBy { key }.mapValues { it.value.count() }

or, more efficiently:

items.groupingBy { key }.eachCount()

How do I count the number of occurrences of a char in a String?

This example show you how to count the number of a character occurrences in a string. We show two ways to do it, using the String.replaceAll(String regex, String replace) method and creating a loop that check every char in the String and count the matched char.

package org.kodejava.lang;

public class CharCounter {
    public static void main(String[] args) {
        String text = "a,b,c,c,e,f,g,g,g,g,h";

        // Use the CharCounter.countCharOccurrences() method to count.
        int numberOfLetterC = CharCounter.countCharOccurrences(text, 'c');
        System.out.println("Letter c = " + numberOfLetterC);

        // Other solution is to use the String.replaceAll() method. We'll
        // replace the chars other than the counted char with an empty string.
        // To get the char occurrences we count the length of the remaining
        // string.
        int numberOfComma = text.replaceAll("[^,]", "").length();
        System.out.println("Comma    = " + numberOfComma);

        int numberOfLetterG = text.replaceAll("[^g]", "").length();
        System.out.println("Letter g = " + numberOfLetterG);
    }

    /**
     * Count number of specified char occurrences in the specified string.
     */
    private static int countCharOccurrences(String source, char target) {
        int counter = 0;

        // Loop through the string and increment the counter if the
        // target character found in the string. 
        for (int i = 0; i < source.length(); i++) {
            if (source.charAt(i) == target) {
                counter++;
            }
        }
        return counter;
    }
}