Improve groupingBy samples
This commit is contained in:
@@ -6,8 +6,6 @@
|
||||
package samples.collections
|
||||
|
||||
import samples.*
|
||||
import java.util.stream.Collector
|
||||
import kotlin.test.*
|
||||
|
||||
class Grouping {
|
||||
|
||||
@@ -25,35 +23,34 @@ class Grouping {
|
||||
|
||||
|
||||
@Sample
|
||||
fun aggregateEvenAndOdd() {
|
||||
val intList = listOf(0, 1, 2, 3, 4, 5, 6)
|
||||
fun aggregateByRadix() {
|
||||
val numbers = listOf(3, 4, 5, 6, 7, 8, 9)
|
||||
|
||||
// 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)
|
||||
}
|
||||
val aggregated = numbers.groupingBy { it % 3 }.aggregate { key, accumulator: StringBuilder?, element, first ->
|
||||
if (first) // first element
|
||||
StringBuilder().append(key).append(":").append(element)
|
||||
else
|
||||
accumulator!!.append("-").append(element)
|
||||
}
|
||||
|
||||
assertPrints(aggregated, "{true=120, false=9}")
|
||||
assertPrints(aggregated.values, "[0:3-6-9, 1:4-7, 2:5-8]")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun aggregateEvenAndOddTo() {
|
||||
val intList = listOf(0, 1, 2, 3, 4, 5, 6)
|
||||
val aggregated = mutableMapOf<Boolean, Int>()
|
||||
fun aggregateByRadixTo() {
|
||||
val numbers = listOf(3, 4, 5, 6, 7, 8, 9)
|
||||
|
||||
// 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)
|
||||
}
|
||||
})
|
||||
val aggregated = numbers.groupingBy { it % 3 }.aggregateTo(mutableMapOf()) { key, accumulator: StringBuilder?, element, first ->
|
||||
if (first) // first element
|
||||
StringBuilder().append(key).append(":").append(element)
|
||||
else
|
||||
accumulator!!.append("-").append(element)
|
||||
}
|
||||
|
||||
assertTrue(aggregated[true] == 120)
|
||||
assertTrue(aggregated[false] == 9)
|
||||
assertPrints(aggregated.values, "[0:3-6-9, 1:4-7, 2:5-8]")
|
||||
|
||||
// aggregated is a mutable map
|
||||
aggregated.clear()
|
||||
}
|
||||
|
||||
@Sample
|
||||
@@ -63,8 +60,7 @@ class Grouping {
|
||||
val evenFruits = fruits.groupingBy { it.first() }
|
||||
.fold({ key, _ -> key to mutableListOf<String>() },
|
||||
{ _, accumulator, element ->
|
||||
if (element.length % 2 == 0) accumulator.second.add(element)
|
||||
accumulator
|
||||
accumulator.also { (_, list) -> if (element.length % 2 == 0) list.add(element) }
|
||||
})
|
||||
|
||||
val sorted = evenFruits.values.sortedBy { it.first }
|
||||
@@ -74,25 +70,18 @@ class Grouping {
|
||||
@Sample
|
||||
fun foldByEvenLengthWithComputedInitialValueTo() {
|
||||
val fruits = listOf("cherry", "blueberry", "citrus", "apple", "apricot", "banana", "coconut")
|
||||
val evenFruits = mutableMapOf<Char, Pair<Char, MutableList<String>>>()
|
||||
|
||||
fruits.groupingBy { it.first() }
|
||||
.foldTo(evenFruits, { key, _: String -> key to mutableListOf() },
|
||||
val evenFruits = fruits.groupingBy { it.first() }
|
||||
.foldTo(mutableMapOf(), { key, _: String -> key to mutableListOf<String>() },
|
||||
{ _, 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])]")
|
||||
|
||||
assertTrue(sorted.first().first == 'a')
|
||||
assertTrue(sorted[0].second == emptyList<String>())
|
||||
|
||||
assertTrue(sorted[1].first == 'b')
|
||||
assertTrue(sorted[1].second == listOf("banana"))
|
||||
|
||||
assertTrue(sorted.last().first == 'c')
|
||||
assertTrue(sorted.last().second == listOf("cherry", "citrus"))
|
||||
evenFruits.clear() // evenFruits is a mutable map
|
||||
}
|
||||
|
||||
@Sample
|
||||
@@ -109,51 +98,43 @@ class Grouping {
|
||||
@Sample
|
||||
fun foldByEvenLengthWithConstantInitialValueTo() {
|
||||
val fruits = listOf("apple", "apricot", "banana", "blueberry", "cherry", "coconut")
|
||||
val evenFruits = mutableMapOf<Char, List<String>>()
|
||||
|
||||
// collect only even length Strings
|
||||
fruits.groupingBy { it.first() }
|
||||
.foldTo(evenFruits, listOf()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
|
||||
val evenFruits = fruits.groupingBy { it.first() }
|
||||
.foldTo(mutableMapOf(), emptyList<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
|
||||
|
||||
assertTrue(evenFruits['a'] == emptyList<String>())
|
||||
assertTrue(evenFruits['b'] == listOf("banana"))
|
||||
assertTrue(evenFruits['c'] == listOf("cherry"))
|
||||
assertPrints(evenFruits, "{a=[], b=[banana], c=[cherry]}")
|
||||
|
||||
evenFruits.clear() // evenFruits is a mutable map
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun reduceByMaxOfContainsVowels() {
|
||||
fun reduceByMaxVowels() {
|
||||
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
|
||||
}
|
||||
}
|
||||
val compareByVowelCount = compareBy { s: String -> s.count { it in "aeiou" } }
|
||||
|
||||
val maxVowels = animals.groupingBy { it.first() }.reduce { _, a, b -> maxOf(a, b, compareByVowelCount) }
|
||||
|
||||
assertPrints(maxVowels, "{r=reindeer, c=camel, g=giraffe}")
|
||||
}
|
||||
|
||||
@Sample
|
||||
fun reduceByMaxOfContainsVowelsTo() {
|
||||
fun reduceByMaxVowelsTo() {
|
||||
val animals = listOf("raccoon", "reindeer", "cow", "camel", "giraffe", "goat")
|
||||
val maxVowels = mutableMapOf<Char, String>()
|
||||
|
||||
// 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
|
||||
}
|
||||
})
|
||||
val compareByVowelCount = compareBy { s: String -> s.count { it in "aeiou" } }
|
||||
|
||||
assertTrue(maxVowels['r'] == "reindeer")
|
||||
assertTrue(maxVowels['c'] == "camel")
|
||||
assertTrue(maxVowels['g'] == "giraffe")
|
||||
animals.groupingBy { it.first() }.reduceTo(maxVowels) { _, a, b -> maxOf(a, b, compareByVowelCount) }
|
||||
|
||||
assertPrints(maxVowels, "{r=reindeer, c=camel, g=giraffe}")
|
||||
|
||||
val moreAnimals = listOf("capybara", "rat")
|
||||
moreAnimals.groupingBy { it.first() }.reduceTo(maxVowels) { _, a, b -> maxOf(a, b, compareByVowelCount) }
|
||||
|
||||
assertPrints(maxVowels, "{r=reindeer, c=capybara, g=giraffe}")
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public interface Grouping<T, out K> {
|
||||
* - `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
|
||||
* @sample samples.collections.Grouping.aggregateByRadix
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public inline fun <T, K, R> Grouping<T, K>.aggregate(
|
||||
@@ -70,7 +70,7 @@ public inline fun <T, K, R> Grouping<T, K>.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
|
||||
* @sample samples.collections.Grouping.aggregateByRadixTo
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public inline fun <T, K, R, M : MutableMap<in K, R>> Grouping<T, K>.aggregateTo(
|
||||
@@ -202,7 +202,7 @@ public inline fun <T, K, R, M : MutableMap<in K, R>> Grouping<T, K>.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
|
||||
* @sample samples.collections.Grouping.reduceByMaxVowels
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public inline fun <S, T : S, K> Grouping<T, K>.reduce(
|
||||
@@ -229,7 +229,7 @@ public inline fun <S, T : S, K> Grouping<T, K>.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
|
||||
* @sample samples.collections.Grouping.reduceByMaxVowelsTo
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public inline fun <S, T : S, K, M : MutableMap<in K, S>> Grouping<T, K>.reduceTo(
|
||||
|
||||
Reference in New Issue
Block a user