Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count occurrences of each tag using functional programming

I've been trying to make a function that returns a Map<String, Int> with the key being a certain tag and the value being the number of occurrences.

The object (simplified) from which I need to extract the info:

class Note {
   List<String> tags
}

The function so far:

private fun extractTags(notes: List<Note>): Map<String, Int> {
    return notes.map { note -> note.tags }
                .groupBy { it }
                .mapValues { it.value.count() }    
}

Right now the compiler gives me a return type mismatch of Map<(Mutable)Set<String!>!, Int> and I'm not certain I'm getting the desired result (as I still can't test this properly).

I'm expecting a result something in the lines of:

(tag1, 1)
(tag2, 4)
(tag3, 14)
...
like image 258
Schadenfreude Avatar asked Jul 24 '17 14:07

Schadenfreude


1 Answers

You can using Iterable#asSequence just like as Java-8 stream-api in Kotlin. then using Sequence#flatMap to merge all tags into a Sequence , and then using Sequence#groupingBy to counting each tag, for example:

private fun extractTags(notes: List<Note>): Map<String, Int> {
    return notes.asSequence()
                .flatMap { it.tags.asSequence() }
                .groupingBy { it }.eachCount()
}

Note: both Sequence#flatMap and Sequence#groupingBy are intermediate operations, which means if the terminal operation Grouping#eachCount is not called. all of the operations on the Sequence is not ran.

like image 66
holi-java Avatar answered Jan 03 '23 21:01

holi-java