b64b96eee6
- Int.toChar was left non-deprecated because the replacement is not intrinsic yet. - Number.toChar was left non-deprecated because otherwise the deprecation propagates to the override, Int.toChar. KT-23451
117 lines
5.0 KiB
Kotlin
117 lines
5.0 KiB
Kotlin
/*
|
|
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
*/
|
|
|
|
package test.collections
|
|
|
|
import kotlin.test.*
|
|
|
|
class GroupingTest {
|
|
|
|
@Test fun groupingProducers() {
|
|
|
|
fun <T, K> verifyGrouping(grouping: Grouping<T, K>, expectedElements: List<T>, expectedKeys: List<K>) {
|
|
val elements = grouping.sourceIterator().asSequence().toList()
|
|
val keys = elements.map { grouping.keyOf(it) } // TODO: replace with grouping::keyOf when supported in JS
|
|
|
|
assertEquals(expectedElements, elements)
|
|
assertEquals(expectedKeys, keys)
|
|
}
|
|
|
|
val elements = listOf("foo", "bar", "value", "x")
|
|
val keySelector: (String) -> Int = { it.length }
|
|
val keys = elements.map(keySelector)
|
|
|
|
fun verifyGrouping(grouping: Grouping<String, Int>) = verifyGrouping(grouping, elements, keys)
|
|
|
|
verifyGrouping(elements.groupingBy { it.length })
|
|
verifyGrouping(elements.toTypedArray().groupingBy(keySelector))
|
|
verifyGrouping(elements.asSequence().groupingBy(keySelector))
|
|
|
|
val charSeq = "some sequence of chars"
|
|
verifyGrouping(charSeq.groupingBy { it.code }, charSeq.toList(), charSeq.map { it.code })
|
|
}
|
|
|
|
// aggregate and aggregateTo operations are not tested, but they're used in every other operation
|
|
|
|
|
|
@Test fun foldWithConstantInitialValue() {
|
|
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
|
// only collect strings with even length
|
|
val result = elements.groupingBy { it.first() }.fold(listOf<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
|
|
|
|
assertEquals(mapOf('f' to listOf("flea"), 'b' to emptyList(), 'z' to emptyList()), result)
|
|
|
|
val moreElements = listOf("fire", "zero", "abstract")
|
|
val result2 = moreElements.groupingBy { it.first() }.foldTo(HashMap(result), listOf()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
|
|
|
|
assertEquals(mapOf('f' to listOf("flea", "fire"), 'b' to emptyList(), 'z' to listOf("zero"), 'a' to listOf("abstract")), result2)
|
|
}
|
|
|
|
data class Collector<out K, V>(val key: K, val values: MutableList<V> = mutableListOf<V>())
|
|
|
|
@Test fun foldWithComputedInitialValue() {
|
|
|
|
fun <K> Collector<K, String>.accumulateIfEven(e: String) = apply { if (e.length % 2 == 0) values.add(e) }
|
|
fun <K, V> Collector<K, V>.toPair() = key to values as List<V>
|
|
|
|
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
|
val result = elements.groupingBy { it.first() }
|
|
.fold({ k, _ -> Collector<Char, String>(k) }, { _, acc, e -> acc.accumulateIfEven(e) })
|
|
|
|
val ordered = result.values.sortedBy { it.key }.map { it.toPair() }
|
|
assertEquals(listOf('b' to emptyList(), 'f' to listOf("flea"), 'z' to emptyList()), ordered)
|
|
|
|
val moreElements = listOf("fire", "zero")
|
|
val result2 = moreElements.groupingBy { it.first() }
|
|
.foldTo(HashMap(result),
|
|
{ k, _ -> error("should not be called for $k") },
|
|
{ _, acc, e -> acc.accumulateIfEven(e) })
|
|
|
|
val ordered2 = result2.values.sortedBy { it.key }.map { it.toPair() }
|
|
assertEquals(listOf('b' to emptyList(), 'f' to listOf("flea", "fire"), 'z' to listOf("zero")), ordered2)
|
|
}
|
|
|
|
inline fun <T, K : Comparable<K>> maxOfBy(a: T, b: T, keySelector: (T) -> K) = if (keySelector(a) >= keySelector(b)) a else b
|
|
|
|
@Test fun reduce() {
|
|
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
|
fun Char.isVowel() = this in "aeiou"
|
|
fun String.countVowels() = count(Char::isVowel)
|
|
val maxVowels = elements.groupingBy { it.first() }.reduce { _, a, b -> maxOfBy(a, b, String::countVowels) }
|
|
|
|
assertEquals(mapOf('f' to "foo", 'b' to "biscuit", 'z' to "zoo"), maxVowels)
|
|
|
|
val elements2 = listOf("bar", "z", "fork")
|
|
val concats = elements2.groupingBy { it.first() }.reduceTo(HashMap(maxVowels)) { _, acc, e -> acc + e }
|
|
|
|
assertEquals(mapOf('f' to "foofork", 'b' to "biscuitbar", 'z' to "zooz"), concats)
|
|
}
|
|
|
|
@Test fun countEach() {
|
|
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
|
val counts = elements.groupingBy { it.first() }.eachCount()
|
|
|
|
assertEquals(mapOf('f' to 2, 'b' to 2, 'z' to 1), counts)
|
|
|
|
val elements2 = arrayOf("zebra", "baz", "cab")
|
|
val counts2 = elements2.groupingBy { it.last() }.eachCountTo(HashMap(counts))
|
|
|
|
assertEquals(mapOf('f' to 2, 'b' to 3, 'a' to 1, 'z' to 2), counts2)
|
|
}
|
|
|
|
/*
|
|
@Test fun sumEach() {
|
|
val values = listOf("k" to 50, "b" to 20, "k" to 1000 )
|
|
val summary = values.groupingBy { it.first }.eachSumOf { it.second }
|
|
|
|
assertEquals(mapOf("k" to 1050, "b" to 20), summary)
|
|
|
|
val values2 = listOf("key", "ball", "builder", "alpha")
|
|
val summary2 = values2.groupingBy { it.first().toString() }.eachSumOfTo(HashMap(summary)) { it.length }
|
|
|
|
assertEquals(mapOf("k" to 1053, "b" to 31, "a" to 5), summary2)
|
|
}
|
|
*/
|
|
} |