diff --git a/stdlib/ktSrc/JavaIterables.kt b/stdlib/ktSrc/JavaIterables.kt index 438b29dc388..e209250b1fc 100644 --- a/stdlib/ktSrc/JavaIterables.kt +++ b/stdlib/ktSrc/JavaIterables.kt @@ -81,6 +81,20 @@ inline fun java.lang.Iterable.foreach(operation: (element: T) -> Unit) { operation(elem) } +/** + * Iterates through the collection performing the transformation on each element and using the result + * as the key in a map to group elements by the result + */ +inline fun java.lang.Iterable.groupBy(result: Map> = HashMap>(), toKey: (T)-> K) : Map> { + for (elem in this) { + val key = toKey(elem) + val list = result.getOrElseUpdate(key){ ArrayList() } + list.add(elem) + } + return result +} + + /** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */ inline fun java.lang.Iterable.join(separator: String, prefix: String = "", postfix: String = "") : String { val buffer = StringBuilder(prefix) diff --git a/testlib/test/CollectionTest.kt b/testlib/test/CollectionTest.kt index 926c300862c..e26e264f8c5 100644 --- a/testlib/test/CollectionTest.kt +++ b/testlib/test/CollectionTest.kt @@ -118,6 +118,24 @@ class CollectionTest() : TestSupport() { assertEquals(6, count) } + fun testGroupBy() { + val words = arrayList("a", "ab", "abc", "def", "abcd") + /* + TODO inference engine should not need this type info? + */ + val byLength = words.groupBy{it.length} + assertEquals(4, byLength.size()) + + println("Grouped by length is: $byLength") + /* + TODO compiler bug... + + val l3 = byLength.getOrElse(3, {ArrayList()}) + assertEquals(2, l3.size) + */ + + } + fun testJoin() { val text = data.join("-", "<", ">") assertEquals("", text)