diff --git a/libraries/stdlib/samples/test/samples/collections/grouping.kt b/libraries/stdlib/samples/test/samples/collections/grouping.kt new file mode 100644 index 00000000000..f9e0acfb222 --- /dev/null +++ b/libraries/stdlib/samples/test/samples/collections/grouping.kt @@ -0,0 +1,145 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package samples.collections + +import samples.* +import java.util.stream.Collector +import kotlin.test.* + +class Grouping { + @Sample + fun aggregateEvenAndOdd() { + val intList = listOf(0, 1, 2, 3, 4, 5, 6) + + // to multiply even number by 10 + val aggregated = intList.groupingBy { it % 2 == 0 }.aggregate { key, acc: Int?, element, _ -> + when (key) { + true -> element * 10 + (acc ?: 0) + else -> element + (acc ?: 0) + } + } + + assertPrints(aggregated, "{true=120, false=9}") + } + + @Sample + fun aggregateEvenAndOddTo() { + val intList = listOf(0, 1, 2, 3, 4, 5, 6) + val aggregated = mutableMapOf() + + // to multiply even number by 10 + intList.groupingBy { it % 2 == 0 }.aggregateTo(aggregated, { key, acc: Int?, element, _ -> + when (key) { + true -> element * 10 + (acc ?: 0) + else -> element + (acc ?: 0) + } + }) + + assertTrue(aggregated[true] == 120) + assertTrue(aggregated[false] == 9) + } + + @Sample + fun foldByEvenLengthWithComputedInitialValue() { + val fruits = listOf("cherry", "blueberry", "citrus", "apple", "apricot", "banana", "coconut") + + val evenFruits = fruits.groupingBy { it.first() } + .fold({ key, _ -> key to mutableListOf() }, + { _, accumulator, element -> + if (element.length % 2 == 0) accumulator.second.add(element) + accumulator + }) + + val sorted = evenFruits.values.sortedBy { it.first } + assertPrints(sorted, "[(a, []), (b, [banana]), (c, [cherry, citrus])]") + } + + @Sample + fun foldByEvenLengthWithComputedInitialValueTo() { + val fruits = listOf("cherry", "blueberry", "citrus", "apple", "apricot", "banana", "coconut") + val evenFruits = mutableMapOf>>() + + fruits.groupingBy { it.first() } + .foldTo(evenFruits, { key, _: String -> key to mutableListOf() }, + { _, accumulator, element -> + if (element.length % 2 == 0) accumulator.second.add(element) + accumulator + }) + + val sorted = evenFruits.values.sortedBy { it.first } + + assertTrue(sorted.first().first == 'a') + assertTrue(sorted[0].second == emptyList()) + + assertTrue(sorted[1].first == 'b') + assertTrue(sorted[1].second == listOf("banana")) + + assertTrue(sorted.last().first == 'c') + assertTrue(sorted.last().second == listOf("cherry", "citrus")) + } + + @Sample + fun foldByEvenLengthWithConstantInitialValue() { + val fruits = listOf("apple", "apricot", "banana", "blueberry", "cherry", "coconut") + + // collect only even length Strings + val evenFruits = fruits.groupingBy { it.first() } + .fold(listOf()) { acc, e -> if (e.length % 2 == 0) acc + e else acc } + + assertPrints(evenFruits, "{a=[], b=[banana], c=[cherry]}") + } + + @Sample + fun foldByEvenLengthWithConstantInitialValueTo() { + val fruits = listOf("apple", "apricot", "banana", "blueberry", "cherry", "coconut") + val evenFruits = mutableMapOf>() + + // collect only even length Strings + fruits.groupingBy { it.first() } + .foldTo(evenFruits, listOf()) { acc, e -> if (e.length % 2 == 0) acc + e else acc } + + assertTrue(evenFruits['a'] == emptyList()) + assertTrue(evenFruits['b'] == listOf("banana")) + assertTrue(evenFruits['c'] == listOf("cherry")) + } + + @Sample + fun reduceByMaxOfContainsVowels() { + val animals = listOf("raccoon", "reindeer", "cow", "camel", "giraffe", "goat") + + // grouping by first char and collect only max of contains vowels + val maxVowels = animals.groupingBy { it.first() } + .reduce { _, a, b -> + if (a.count { it in "aeiou" } >= b.count { it in "aeiou" }) { + a + } else { + b + } + } + + assertPrints(maxVowels, "{r=reindeer, c=camel, g=giraffe}") + } + + @Sample + fun reduceByMaxOfContainsVowelsTo() { + val animals = listOf("raccoon", "reindeer", "cow", "camel", "giraffe", "goat") + val maxVowels = mutableMapOf() + + // grouping by first char and collect only max of contains vowels + animals.groupingBy { it.first() } + .reduceTo(maxVowels, { _, a, b -> + if (a.count { it in "aeiou" } >= b.count { it in "aeiou" }) { + a + } else { + b + } + }) + + assertTrue(maxVowels['r'] == "reindeer") + assertTrue(maxVowels['c'] == "camel") + assertTrue(maxVowels['g'] == "giraffe") + } +} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/collections/Grouping.kt b/libraries/stdlib/src/kotlin/collections/Grouping.kt index 206c5906f83..ee7517b3e69 100644 --- a/libraries/stdlib/src/kotlin/collections/Grouping.kt +++ b/libraries/stdlib/src/kotlin/collections/Grouping.kt @@ -44,6 +44,7 @@ public interface Grouping { * - `first`: indicates whether it's the first `element` encountered in the group. * * @return a [Map] associating the key of each group with the result of aggregation of the group elements. + * @sample samples.collections.Grouping.aggregateEvenAndOdd */ @SinceKotlin("1.1") public inline fun Grouping.aggregate( @@ -69,6 +70,7 @@ public inline fun Grouping.aggregate( * then the elements being aggregated for that key are never considered as `first`. * * @return the [destination] map associating the key of each group with the result of aggregation of the group elements. + * @sample samples.collections.Grouping.aggregateEvenAndOddTo */ @SinceKotlin("1.1") public inline fun > Grouping.aggregateTo( @@ -99,6 +101,7 @@ public inline fun > Grouping.aggregateTo( * - `element`: the element from the source being accumulated. * * @return a [Map] associating the key of each group with the result of accumulating the group elements. + * @sample samples.collections.Grouping.foldByEvenLengthWithComputedInitialValue */ @SinceKotlin("1.1") public inline fun Grouping.fold( @@ -128,6 +131,7 @@ public inline fun Grouping.fold( * - `element`: the element from the source being accumulated. * * @return the [destination] map associating the key of each group with the result of accumulating the group elements. + * @sample samples.collections.Grouping.foldByEvenLengthWithComputedInitialValueTo */ @SinceKotlin("1.1") public inline fun > Grouping.foldTo( @@ -149,6 +153,7 @@ public inline fun > Grouping.foldTo( * - `element`: the element from the source being accumulated. * * @return a [Map] associating the key of each group with the result of accumulating the group elements. + * @sample samples.collections.Grouping.foldByEvenLengthWithConstantInitialValue */ @SinceKotlin("1.1") public inline fun Grouping.fold( @@ -172,6 +177,7 @@ public inline fun Grouping.fold( * - `element`: the element from the source being accumulated. * * @return the [destination] map associating the key of each group with the result of accumulating the group elements. + * @sample samples.collections.Grouping.foldByEvenLengthWithConstantInitialValueTo */ @SinceKotlin("1.1") public inline fun > Grouping.foldTo( @@ -196,6 +202,7 @@ public inline fun > Grouping.foldTo( * - `element`: the element from the source being accumulated. * * @return a [Map] associating the key of each group with the result of accumulating the group elements. + * @sample samples.collections.Grouping.reduceByMaxOfContainsVowels */ @SinceKotlin("1.1") public inline fun Grouping.reduce( @@ -222,6 +229,7 @@ public inline fun Grouping.reduce( * - `element`: the element from the source being folded; * * @return the [destination] map associating the key of each group with the result of accumulating the group elements. + * @sample samples.collections.Grouping.reduceByMaxOfContainsVowelsTo */ @SinceKotlin("1.1") public inline fun > Grouping.reduceTo(