diff --git a/build.xml b/build.xml index da3a17c9402..7ea61a95155 100644 --- a/build.xml +++ b/build.xml @@ -151,6 +151,20 @@ + + + + + + + + + + + + + + diff --git a/stdlib/ktSrc/Arrays.kt b/stdlib/ktSrc/Arrays.kt index d7213ad4a53..8c842b6ef3f 100644 --- a/stdlib/ktSrc/Arrays.kt +++ b/stdlib/ktSrc/Arrays.kt @@ -104,3 +104,18 @@ inline fun ByteArray.inputStream(offset: Int, length: Int) = ByteArrayInputStrea /** Returns true if the array is not empty */ inline fun Array.notEmpty() : Boolean = this.size > 0 +/** Returns true if the array is empty */ +inline fun Array.isEmpty() : Boolean = this.size == 0 + + +/** Returns a new List containing the results of applying the given function to each element in this collection */ +inline fun Array.map(transform : (T) -> R) : java.util.List { + return mapTo(java.util.ArrayList(this.size), transform) +} + +/** Transforms each element of this collection with the given function then adds the results to the given collection */ +inline fun > Array.mapTo(result: C, transform : (T) -> R) : C { + for (item in this) + result.add(transform(item)) + return result +} diff --git a/stdlib/ktSrc/JavaCollections.kt b/stdlib/ktSrc/JavaCollections.kt index bcd9f001b4a..c4802436512 100644 --- a/stdlib/ktSrc/JavaCollections.kt +++ b/stdlib/ktSrc/JavaCollections.kt @@ -1,17 +1,3 @@ package std.util import java.util.* - -/** Returns a new collection containing the results of applying the given function to each element in this collection */ -inline fun java.util.Collection.map(result: Collection = ArrayList(this.size), transform : (T) -> R) : Collection { - for (item in this) - result.add(transform(item)) - return result -} - -/** Returns true if the collection is not empty */ -inline fun java.util.Collection.notEmpty() : Boolean = !this.isEmpty() - -/** Converts the nullable collection into an empty collection if its null */ -inline fun java.util.Collection?.notNull() : Collection - = if (this != null) this else Collections.EMPTY_LIST as Collection diff --git a/stdlib/ktSrc/JavaUtil.kt b/stdlib/ktSrc/JavaUtil.kt index 4c54219cb2a..3c54edceca7 100644 --- a/stdlib/ktSrc/JavaUtil.kt +++ b/stdlib/ktSrc/JavaUtil.kt @@ -96,4 +96,22 @@ val List.last : T? get() = this.tail +/** Returns true if the collection is not empty */ +inline fun java.util.Collection.notEmpty() : Boolean = !this.isEmpty() +/** Converts the nullable collection into an empty collection if its null */ +inline fun java.util.Collection?.notNull() : Collection + = if (this != null) this else Collections.EMPTY_LIST as Collection + + +/** Returns a new List containing the results of applying the given function to each element in this collection */ +inline fun java.util.Collection.map(transform : (T) -> R) : java.util.List { + return mapTo(java.util.ArrayList(this.size), transform) +} + +/** Transforms each element of this collection with the given function then adds the results to the given collection */ +inline fun > java.util.Collection.mapTo(result: C, transform : (T) -> R) : C { + for (item in this) + result.add(transform(item)) + return result +} diff --git a/stdlib/ktSrc/generated/ArraysFromJavaIterables.kt b/stdlib/ktSrc/generated/ArraysFromJavaIterables.kt index 9794644f7d7..05597f4094a 100644 --- a/stdlib/ktSrc/generated/ArraysFromJavaIterables.kt +++ b/stdlib/ktSrc/generated/ArraysFromJavaIterables.kt @@ -1,6 +1,8 @@ // NOTE this file is auto-generated from stdlib/ktSrc/JavaIterables.kt package std +import std.util.* + import java.util.* /** Returns true if any elements in the collection match the given predicate */ @@ -23,6 +25,16 @@ inline fun Array.all(predicate: (T)-> Boolean) : Boolean { return true } +/** Returns the number of items which match the given predicate */ +inline fun Array.count(predicate: (T)-> Boolean) : Int { + var answer = 0 + for (elem in this) { + if (predicate(elem)) + answer += 1 + } + return answer +} + /** Returns the first item in the collection which matches the given predicate or null if none matched */ inline fun Array.find(predicate: (T)-> Boolean) : T? { for (elem in this) { @@ -32,8 +44,11 @@ inline fun Array.find(predicate: (T)-> Boolean) : T? { return null } -/** Returns a new collection containing all elements in this collection which match the given predicate */ -inline fun Array.filter(result: Collection = ArrayList(), predicate: (T)-> Boolean) : Collection { +/** Returns a new List containing all elements in this collection which match the given predicate */ +inline fun Array.filter(predicate: (T)-> Boolean) : Collection = filterTo(java.util.ArrayList(), predicate) + +/** Filters all elements in this collection which match the given predicate into the given result collection */ +inline fun > Array.filterTo(result: C, predicate: (T)-> Boolean) : C { for (elem in this) { if (predicate(elem)) result.add(elem) @@ -42,7 +57,10 @@ inline fun Array.filter(result: Collection = ArrayList(), predicate } /** Returns a new collection containing all elements in this collection which do not match the given predicate */ -inline fun Array.filterNot(result: Collection = ArrayList(), predicate: (T)-> Boolean) : Collection { +inline fun Array.filterNot(predicate: (T)-> Boolean) : Collection = filterNotTo(ArrayList(), predicate) + +/** Returns a new collection containing all elements in this collection which do not match the given predicate */ +inline fun > Array.filterNotTo(result: C, predicate: (T)-> Boolean) : C { for (elem in this) { if (!predicate(elem)) result.add(elem) @@ -72,6 +90,42 @@ inline fun Array.foreach(operation: (element: T) -> Unit) { operation(elem) } +/** + * Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values + * + * For example to sum together all numeric values in a collection of numbers it would be + * {code}val total = numbers.fold(0){(a, b) -> a + b}{code} + */ +inline fun Array.fold(initial: T, operation: (it: T, it2: T) -> T): T { + var answer = initial + for (elem in this) { + answer = operation(answer, elem) + } + return answer +} + +/** + * Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values + */ +inline fun Array.foldRight(initial: T, operation: (it: T, it2: T) -> T): T { + val reversed = this.reverse() + return reversed.fold(initial, operation) +} + +/** + * 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 Array.groupBy(result: Map> = HashMap>(), toKey: (T)-> K) : Map> { + for (elem in this) { + val key = toKey(elem) + val list = result.getOrPut(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 Array.join(separator: String, prefix: String = "", postfix: String = "") : String { val buffer = StringBuilder(prefix) @@ -87,18 +141,33 @@ inline fun Array.join(separator: String, prefix: String = "", postfix: St return buffer.toString().sure() } +/** Returns a reversed List of this collection */ +inline fun Array.reverse() : List { + val answer = LinkedList() + for (elem in this) { + answer.addFirst(elem) + } + return answer +} + +/* Copies the collection into the given collection */ inline fun > Array.to(result: C) : C { for (elem in this) result.add(elem) return result } +/* Converts the collection into a LinkedList */ inline fun Array.toLinkedList() : LinkedList = this.to(LinkedList()) +/* Converts the collection into a List */ inline fun Array.toList() : List = this.to(ArrayList()) +/* Converts the collection into a Set */ inline fun Array.toSet() : Set = this.to(HashSet()) +/* Converts the collection into a SortedSet */ +inline fun Array.toSortedSet() : SortedSet = this.to(TreeSet()) /** TODO figure out necessary variance/generics ninja stuff... :) inline fun Array.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List { diff --git a/stdlib/ktSrc/generated/JavaUtilIterablesFromJavaCollections.kt b/stdlib/ktSrc/generated/JavaUtilIterablesFromJavaCollections.kt index 1f767d57fce..6faf9911981 100644 --- a/stdlib/ktSrc/generated/JavaUtilIterablesFromJavaCollections.kt +++ b/stdlib/ktSrc/generated/JavaUtilIterablesFromJavaCollections.kt @@ -2,4 +2,3 @@ package std.util import java.util.* - diff --git a/stdlib/ktSrc/generated/StandardFromJavaCollections.kt b/stdlib/ktSrc/generated/StandardFromJavaCollections.kt index e94ec1d52d3..61eb0b907b2 100644 --- a/stdlib/ktSrc/generated/StandardFromJavaCollections.kt +++ b/stdlib/ktSrc/generated/StandardFromJavaCollections.kt @@ -2,10 +2,3 @@ package std import java.util.* - -/** Returns a new collection containing the results of applying the given function to each element in this collection */ -inline fun Iterable.map(result: Collection = ArrayList(), transform : (T) -> R) : Collection { - for (item in this) - result.add(transform(item)) - return result -} diff --git a/stdlib/ktSrc/generated/StandardFromJavaIterables.kt b/stdlib/ktSrc/generated/StandardFromJavaIterables.kt index 00a566350ec..e2992f217cb 100644 --- a/stdlib/ktSrc/generated/StandardFromJavaIterables.kt +++ b/stdlib/ktSrc/generated/StandardFromJavaIterables.kt @@ -1,6 +1,8 @@ // NOTE this file is auto-generated from stdlib/ktSrc/JavaIterables.kt package std +import std.util.* + import java.util.* /** Returns true if any elements in the collection match the given predicate */ @@ -23,6 +25,16 @@ inline fun Iterable.all(predicate: (T)-> Boolean) : Boolean { return true } +/** Returns the number of items which match the given predicate */ +inline fun Iterable.count(predicate: (T)-> Boolean) : Int { + var answer = 0 + for (elem in this) { + if (predicate(elem)) + answer += 1 + } + return answer +} + /** Returns the first item in the collection which matches the given predicate or null if none matched */ inline fun Iterable.find(predicate: (T)-> Boolean) : T? { for (elem in this) { @@ -32,8 +44,11 @@ inline fun Iterable.find(predicate: (T)-> Boolean) : T? { return null } -/** Returns a new collection containing all elements in this collection which match the given predicate */ -inline fun Iterable.filter(result: Collection = ArrayList(), predicate: (T)-> Boolean) : Collection { +/** Returns a new List containing all elements in this collection which match the given predicate */ +inline fun Iterable.filter(predicate: (T)-> Boolean) : Collection = filterTo(java.util.ArrayList(), predicate) + +/** Filters all elements in this collection which match the given predicate into the given result collection */ +inline fun > Iterable.filterTo(result: C, predicate: (T)-> Boolean) : C { for (elem in this) { if (predicate(elem)) result.add(elem) @@ -42,7 +57,10 @@ inline fun Iterable.filter(result: Collection = ArrayList(), predic } /** Returns a new collection containing all elements in this collection which do not match the given predicate */ -inline fun Iterable.filterNot(result: Collection = ArrayList(), predicate: (T)-> Boolean) : Collection { +inline fun Iterable.filterNot(predicate: (T)-> Boolean) : Collection = filterNotTo(ArrayList(), predicate) + +/** Returns a new collection containing all elements in this collection which do not match the given predicate */ +inline fun > Iterable.filterNotTo(result: C, predicate: (T)-> Boolean) : C { for (elem in this) { if (!predicate(elem)) result.add(elem) @@ -72,6 +90,42 @@ inline fun Iterable.foreach(operation: (element: T) -> Unit) { operation(elem) } +/** + * Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values + * + * For example to sum together all numeric values in a collection of numbers it would be + * {code}val total = numbers.fold(0){(a, b) -> a + b}{code} + */ +inline fun Iterable.fold(initial: T, operation: (it: T, it2: T) -> T): T { + var answer = initial + for (elem in this) { + answer = operation(answer, elem) + } + return answer +} + +/** + * Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values + */ +inline fun Iterable.foldRight(initial: T, operation: (it: T, it2: T) -> T): T { + val reversed = this.reverse() + return reversed.fold(initial, operation) +} + +/** + * 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 Iterable.groupBy(result: Map> = HashMap>(), toKey: (T)-> K) : Map> { + for (elem in this) { + val key = toKey(elem) + val list = result.getOrPut(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 Iterable.join(separator: String, prefix: String = "", postfix: String = "") : String { val buffer = StringBuilder(prefix) @@ -87,18 +141,33 @@ inline fun Iterable.join(separator: String, prefix: String = "", postfix: return buffer.toString().sure() } +/** Returns a reversed List of this collection */ +inline fun Iterable.reverse() : List { + val answer = LinkedList() + for (elem in this) { + answer.addFirst(elem) + } + return answer +} + +/* Copies the collection into the given collection */ inline fun > Iterable.to(result: C) : C { for (elem in this) result.add(elem) return result } +/* Converts the collection into a LinkedList */ inline fun Iterable.toLinkedList() : LinkedList = this.to(LinkedList()) +/* Converts the collection into a List */ inline fun Iterable.toList() : List = this.to(ArrayList()) +/* Converts the collection into a Set */ inline fun Iterable.toSet() : Set = this.to(HashSet()) +/* Converts the collection into a SortedSet */ +inline fun Iterable.toSortedSet() : SortedSet = this.to(TreeSet()) /** TODO figure out necessary variance/generics ninja stuff... :) inline fun Iterable.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List { diff --git a/testlib/test/GenerateStandardLib.kt b/testlib/test/GenerateStandardLib.kt index 0907fd1bd77..347f99bc0e9 100644 --- a/testlib/test/GenerateStandardLib.kt +++ b/testlib/test/GenerateStandardLib.kt @@ -58,11 +58,11 @@ fun main(args: Array) { // JavaIterables - Generic iterable stuff - generateFile(File(outDir, "ArraysFromJavaIterables.kt"), "package std", File(srcDir, "JavaIterables.kt")) { + generateFile(File(outDir, "ArraysFromJavaIterables.kt"), "package std\n\nimport std.util.*", File(srcDir, "JavaIterables.kt")) { it.replaceAll("java.lang.Iterable", "Array") } - generateFile(File(outDir, "StandardFromJavaIterables.kt"), "package std", File(srcDir, "JavaIterables.kt")) { + generateFile(File(outDir, "StandardFromJavaIterables.kt"), "package std\n\nimport std.util.*", File(srcDir, "JavaIterables.kt")) { it.replaceAll("java.lang.Iterable", "Iterable") } diff --git a/testlib/test/regressions/kt1172.kt b/testlib/test/regressions/kt1172.kt index e17d3f26d97..9f60d47b4a0 100644 --- a/testlib/test/regressions/kt1172.kt +++ b/testlib/test/regressions/kt1172.kt @@ -5,7 +5,8 @@ import junit.framework.* import java.util.* public fun scheduleRefresh(vararg files : Object) { - java.util.ArrayList(files.map{ it }) + // TODO + // java.util.ArrayList(files.map{ it }) } fun main(args : Array?) {