Support String in generators, and migrate generated functions.
This commit is contained in:
committed by
Andrey Breslav
parent
d9d5631a16
commit
cbc0e6404e
@@ -115,6 +115,15 @@ public inline fun <T> Stream<T>.all(predicate: (T) -> Boolean) : Boolean {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if all elements match the given *predicate*
|
||||
*/
|
||||
public inline fun String.all(predicate: (Char) -> Boolean) : Boolean {
|
||||
for (element in this) if (!predicate(element)) return false
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if collection has at least one element
|
||||
*/
|
||||
@@ -223,6 +232,15 @@ public fun <T> Stream<T>.any() : Boolean {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if collection has at least one element
|
||||
*/
|
||||
public fun String.any() : Boolean {
|
||||
for (element in this) return true
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if any element matches the given *predicate*
|
||||
*/
|
||||
@@ -331,6 +349,15 @@ public inline fun <T> Stream<T>.any(predicate: (T) -> Boolean) : Boolean {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if any element matches the given *predicate*
|
||||
*/
|
||||
public inline fun String.any(predicate: (Char) -> Boolean) : Boolean {
|
||||
for (element in this) if (predicate(element)) return true
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements
|
||||
*/
|
||||
@@ -428,6 +455,13 @@ public fun <T> Stream<T>.count() : Int {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements
|
||||
*/
|
||||
public fun String.count() : Int {
|
||||
return size
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements matching the given *predicate*
|
||||
*/
|
||||
@@ -548,6 +582,16 @@ public inline fun <T> Stream<T>.count(predicate: (T) -> Boolean) : Int {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements matching the given *predicate*
|
||||
*/
|
||||
public inline fun String.count(predicate: (Char) -> Boolean) : Int {
|
||||
var count = 0
|
||||
for (element in this) if (predicate(element)) count++
|
||||
return count
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with *initial* value and applying *operation* from left to right to current accumulator value and each element
|
||||
*/
|
||||
@@ -658,6 +702,16 @@ public inline fun <T, R> Stream<T>.fold(initial: R, operation: (R, T) -> R) : R
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with *initial* value and applying *operation* from left to right to current accumulator value and each element
|
||||
*/
|
||||
public inline fun <R> String.fold(initial: R, operation: (R, Char) -> R) : R {
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(accumulator, element)
|
||||
return accumulator
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with *initial* value and applying *operation* from right to left to each element and current accumulator value
|
||||
*/
|
||||
@@ -788,6 +842,19 @@ public inline fun <T, R> List<T>.foldRight(initial: R, operation: (T, R) -> R) :
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with *initial* value and applying *operation* from right to left to each element and current accumulator value
|
||||
*/
|
||||
public inline fun <R> String.foldRight(initial: R, operation: (Char, R) -> R) : R {
|
||||
var index = size - 1
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(get(index--), accumulator)
|
||||
}
|
||||
return accumulator
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given *operation* on each element
|
||||
*/
|
||||
@@ -884,6 +951,14 @@ public inline fun <T> Stream<T>.forEach(operation: (T) -> Unit) : Unit {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given *operation* on each element
|
||||
*/
|
||||
public inline fun String.forEach(operation: (Char) -> Unit) : Unit {
|
||||
for (element in this) operation(element)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest element or null if there are no elements
|
||||
*/
|
||||
@@ -1036,6 +1111,22 @@ public fun <T: Comparable<T>> Stream<T>.max() : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest element or null if there are no elements
|
||||
*/
|
||||
public fun String.max() : Char? {
|
||||
val iterator = iterator()
|
||||
if (!iterator.hasNext()) return null
|
||||
|
||||
var max = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
val e = iterator.next()
|
||||
if (max < e) max = e
|
||||
}
|
||||
return max
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element yielding the largest value of the given function or null if there are no elements
|
||||
*/
|
||||
@@ -1258,6 +1349,27 @@ public inline fun <R: Comparable<R>, T: Any> Stream<T>.maxBy(f: (T) -> R) : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element yielding the largest value of the given function or null if there are no elements
|
||||
*/
|
||||
public inline fun <R: Comparable<R>> String.maxBy(f: (Char) -> R) : Char? {
|
||||
val iterator = iterator()
|
||||
if (!iterator.hasNext()) return null
|
||||
|
||||
var maxElem = iterator.next()
|
||||
var maxValue = f(maxElem)
|
||||
while (iterator.hasNext()) {
|
||||
val e = iterator.next()
|
||||
val v = f(e)
|
||||
if (maxValue < v) {
|
||||
maxElem = e
|
||||
maxValue = v
|
||||
}
|
||||
}
|
||||
return maxElem
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element yielding the largest value of the given function or null if there are no elements
|
||||
*/
|
||||
@@ -1423,6 +1535,22 @@ public fun <T: Comparable<T>> Stream<T>.min() : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest element or null if there are no elements
|
||||
*/
|
||||
public fun String.min() : Char? {
|
||||
val iterator = iterator()
|
||||
if (!iterator.hasNext()) return null
|
||||
|
||||
var min = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
val e = iterator.next()
|
||||
if (min > e) min = e
|
||||
}
|
||||
return min
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element yielding the smallest value of the given function or null if there are no elements
|
||||
*/
|
||||
@@ -1645,6 +1773,27 @@ public inline fun <R: Comparable<R>, T: Any> Stream<T>.minBy(f: (T) -> R) : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element yielding the smallest value of the given function or null if there are no elements
|
||||
*/
|
||||
public inline fun <R: Comparable<R>> String.minBy(f: (Char) -> R) : Char? {
|
||||
val iterator = iterator()
|
||||
if (!iterator.hasNext()) return null
|
||||
|
||||
var minElem = iterator.next()
|
||||
var minValue = f(minElem)
|
||||
while (iterator.hasNext()) {
|
||||
val e = iterator.next()
|
||||
val v = f(e)
|
||||
if (minValue > v) {
|
||||
minElem = e
|
||||
minValue = v
|
||||
}
|
||||
}
|
||||
return minElem
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element yielding the smallest value of the given function or null if there are no elements
|
||||
*/
|
||||
@@ -1774,6 +1923,15 @@ public fun <T> Stream<T>.none() : Boolean {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if collection has no elements
|
||||
*/
|
||||
public fun String.none() : Boolean {
|
||||
for (element in this) return false
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if no elements match the given *predicate*
|
||||
*/
|
||||
@@ -1882,6 +2040,15 @@ public inline fun <T> Stream<T>.none(predicate: (T) -> Boolean) : Boolean {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if no elements match the given *predicate*
|
||||
*/
|
||||
public inline fun String.none(predicate: (Char) -> Boolean) : Boolean {
|
||||
for (element in this) if (predicate(element)) return false
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with the first element and applying *operation* from left to right to current accumulator value and each element
|
||||
*/
|
||||
@@ -2047,6 +2214,21 @@ public inline fun <T> Stream<T>.reduce(operation: (T, T) -> T) : T {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with the first element and applying *operation* from left to right to current accumulator value and each element
|
||||
*/
|
||||
public inline fun String.reduce(operation: (Char, Char) -> Char) : Char {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced")
|
||||
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with last element and applying *operation* from right to left to each element and current accumulator value
|
||||
*/
|
||||
@@ -2207,3 +2389,19 @@ public inline fun <T> List<T>.reduceRight(operation: (T, T) -> T) : T {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with last element and applying *operation* from right to left to each element and current accumulator value
|
||||
*/
|
||||
public inline fun String.reduceRight(operation: (Char, Char) -> Char) : Char {
|
||||
var index = size - 1
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced")
|
||||
|
||||
var accumulator = get(index--)
|
||||
while (index >= 0) {
|
||||
accumulator = operation(get(index--), accumulator)
|
||||
}
|
||||
|
||||
return accumulator
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -211,6 +211,14 @@ public fun <T> Stream<T>.elementAt(index : Int) : T {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns element at given *index*
|
||||
*/
|
||||
public fun String.elementAt(index : Int) : Char {
|
||||
return get(index)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element
|
||||
*/
|
||||
@@ -351,6 +359,16 @@ public fun <T> Stream<T>.first(): T {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element
|
||||
*/
|
||||
public fun String.first() : Char {
|
||||
if (size == 0)
|
||||
throw IllegalArgumentException("Collection is empty")
|
||||
return this[0]
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element matching the given *predicate*
|
||||
*/
|
||||
@@ -450,6 +468,15 @@ public inline fun <T> Stream<T>.first(predicate: (T) -> Boolean) : T {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element matching the given *predicate*
|
||||
*/
|
||||
public inline fun String.first(predicate: (Char) -> Boolean) : Char {
|
||||
for (element in this) if (predicate(element)) return element
|
||||
throw IllegalArgumentException("No element matching predicate was found")
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first elementm, or null if collection is empty
|
||||
*/
|
||||
@@ -570,6 +597,14 @@ public fun <T> Stream<T>.firstOrNull(): T? {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first elementm, or null if collection is empty
|
||||
*/
|
||||
public fun String.firstOrNull() : Char? {
|
||||
return if (size > 0) this[0] else null
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element matching the given *predicate*, or *null* if element was not found
|
||||
*/
|
||||
@@ -669,6 +704,15 @@ public inline fun <T> Stream<T>.firstOrNull(predicate: (T) -> Boolean) : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element matching the given *predicate*, or *null* if element was not found
|
||||
*/
|
||||
public inline fun String.firstOrNull(predicate: (Char) -> Boolean) : Char? {
|
||||
for (element in this) if (predicate(element)) return element
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first index of *element*, or -1 if the collection does not contain element
|
||||
*/
|
||||
@@ -966,6 +1010,16 @@ public fun <T> Stream<T>.last() : T {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last element
|
||||
*/
|
||||
public fun String.last() : Char {
|
||||
if (size == 0)
|
||||
throw IllegalArgumentException("Collection is empty")
|
||||
return this[size - 1]
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last element matching the given *predicate*
|
||||
*/
|
||||
@@ -1464,6 +1518,14 @@ public fun <T> Stream<T>.lastOrNull() : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last element, or null if collection is empty
|
||||
*/
|
||||
public fun String.lastOrNull() : Char? {
|
||||
return if (size > 0) this[size - 1] else null
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last element matching the given *predicate*, or null if element was not found
|
||||
*/
|
||||
@@ -1770,6 +1832,16 @@ public fun <T> Stream<T>.single() : T {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns single element, or throws exception if there is no or more than one element
|
||||
*/
|
||||
public fun String.single() : Char {
|
||||
if (size != 1)
|
||||
throw IllegalArgumentException("Collection has $size elements")
|
||||
return this[0]
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns single element matching the given *predicate*, or throws exception if there is no or more than one element
|
||||
*/
|
||||
@@ -2144,6 +2216,18 @@ public fun <T> Stream<T>.singleOrNull() : T? {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns single element, or null if collection is empty, or throws exception if there is more than one element
|
||||
*/
|
||||
public fun String.singleOrNull() : Char? {
|
||||
if (size == 0)
|
||||
return null
|
||||
if (size != 1)
|
||||
throw IllegalArgumentException("Collection has $size elements")
|
||||
return this[0]
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns single element matching the given *predicate*, or null if element was not found or more than one elements were found
|
||||
*/
|
||||
|
||||
@@ -189,6 +189,13 @@ public fun <T> Stream<T>.drop(n: Int) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements except first *n* elements
|
||||
*/
|
||||
public fun String.drop(n: Int) : String {
|
||||
return substring(Math.min(n, size))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements except first elements that satisfy the given *predicate*
|
||||
*/
|
||||
@@ -376,6 +383,18 @@ public fun <T> Stream<T>.dropWhile(predicate: (T)->Boolean) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements except first elements that satisfy the given *predicate*
|
||||
*/
|
||||
public inline fun String.dropWhile(predicate: (Char) -> Boolean): String {
|
||||
for (index in 0..length)
|
||||
if (!predicate(get(index))) {
|
||||
return substring(index)
|
||||
}
|
||||
return ""
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements matching the given *predicate*
|
||||
*/
|
||||
@@ -472,6 +491,14 @@ public fun <T> Stream<T>.filter(predicate: (T)->Boolean) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements matching the given *predicate*
|
||||
*/
|
||||
public inline fun String.filter(predicate: (Char)->Boolean) : String {
|
||||
return filterTo(StringBuilder(), predicate).toString()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements not matching the given *predicate*
|
||||
*/
|
||||
@@ -568,6 +595,14 @@ public fun <T> Stream<T>.filterNot(predicate: (T)->Boolean) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements not matching the given *predicate*
|
||||
*/
|
||||
public inline fun String.filterNot(predicate: (Char)->Boolean) : String {
|
||||
return filterNotTo(StringBuilder(), predicate).toString()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements that are not null
|
||||
*/
|
||||
@@ -727,6 +762,15 @@ public inline fun <T, C: MutableCollection<in T>> Stream<T>.filterNotTo(collecti
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all characters not matching the given *predicate* to the given *collection*
|
||||
*/
|
||||
public inline fun <C: Appendable> String.filterNotTo(collection: C, predicate: (Char) -> Boolean) : C {
|
||||
for (element in this) if (!predicate(element)) collection.append(element)
|
||||
return collection
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements matching the given *predicate* into the given *collection*
|
||||
*/
|
||||
@@ -835,6 +879,17 @@ public inline fun <T, C: MutableCollection<in T>> Stream<T>.filterTo(collection:
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all characters matching the given *predicate* to the given *collection*
|
||||
*/
|
||||
public inline fun <C : Appendable> String.filterTo(destination: C, predicate: (Char) -> Boolean): C {
|
||||
for (index in 0..length - 1) {
|
||||
val element = get(index)
|
||||
if (predicate(element)) destination.append(element)
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing elements at specified positions
|
||||
*/
|
||||
@@ -955,6 +1010,18 @@ public fun <T> List<T>.slice(indices: Iterable<Int>) : List<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing elements at specified positions
|
||||
*/
|
||||
public fun String.slice(indices: Iterable<Int>) : String {
|
||||
val result = StringBuilder()
|
||||
for (i in indices) {
|
||||
result.append(get(i))
|
||||
}
|
||||
return result.toString()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing first *n* elements
|
||||
*/
|
||||
@@ -1139,6 +1206,13 @@ public fun <T> Stream<T>.take(n: Int) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing first *n* elements
|
||||
*/
|
||||
public fun String.take(n: Int) : String {
|
||||
return substring(0, Math.min(n, size))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing first elements satisfying the given *predicate*
|
||||
*/
|
||||
@@ -1287,3 +1361,15 @@ public fun <T> Stream<T>.takeWhile(predicate: (T)->Boolean) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing first elements satisfying the given *predicate*
|
||||
*/
|
||||
public inline fun String.takeWhile(predicate: (Char) -> Boolean): String {
|
||||
for (index in 0..length)
|
||||
if (!predicate(get(index))) {
|
||||
return substring(0, index)
|
||||
}
|
||||
return ""
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,25 @@ public inline fun <T> Stream<T>.partition(predicate: (T) -> Boolean) : Pair<List
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits original collection into pair of collections,
|
||||
* where *first* collection contains elements for which predicate yielded *true*,
|
||||
* while *second* collection contains elements for which predicate yielded *false*
|
||||
*/
|
||||
public inline fun String.partition(predicate: (Char) -> Boolean) : Pair<String, String> {
|
||||
val first = StringBuilder()
|
||||
val second = StringBuilder()
|
||||
for (element in this) {
|
||||
if (predicate(element)) {
|
||||
first.append(element)
|
||||
} else {
|
||||
second.append(element)
|
||||
}
|
||||
}
|
||||
return Pair(first.toString(), second.toString())
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements of original collection and then all elements of the given *collection*
|
||||
*/
|
||||
@@ -683,9 +702,37 @@ public fun <T, R> Iterable<T>.zip(array: Array<R>) : List<Pair<T,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <T, R> Array<out T>.zip(collection: Iterable<R>) : List<Pair<T,R>> {
|
||||
public fun <R> String.zip(array: Array<R>) : List<Pair<Char,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = array.iterator()
|
||||
val list = ArrayList<Pair<Char,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
}
|
||||
return list
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of pairs built from characters of both strings with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun String.zip(other : String) : List<Pair<Char,Char>> {
|
||||
val first = iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Char,Char>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
}
|
||||
return list
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <T, R> Array<out T>.zip(other: Iterable<R>) : List<Pair<T,R>> {
|
||||
val first = iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<T,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -697,9 +744,9 @@ public fun <T, R> Array<out T>.zip(collection: Iterable<R>) : List<Pair<T,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> BooleanArray.zip(collection: Iterable<R>) : List<Pair<Boolean,R>> {
|
||||
public fun <R> BooleanArray.zip(other: Iterable<R>) : List<Pair<Boolean,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Boolean,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -711,9 +758,9 @@ public fun <R> BooleanArray.zip(collection: Iterable<R>) : List<Pair<Boolean,R>>
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> ByteArray.zip(collection: Iterable<R>) : List<Pair<Byte,R>> {
|
||||
public fun <R> ByteArray.zip(other: Iterable<R>) : List<Pair<Byte,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Byte,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -725,9 +772,9 @@ public fun <R> ByteArray.zip(collection: Iterable<R>) : List<Pair<Byte,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> CharArray.zip(collection: Iterable<R>) : List<Pair<Char,R>> {
|
||||
public fun <R> CharArray.zip(other: Iterable<R>) : List<Pair<Char,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Char,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -739,9 +786,9 @@ public fun <R> CharArray.zip(collection: Iterable<R>) : List<Pair<Char,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> DoubleArray.zip(collection: Iterable<R>) : List<Pair<Double,R>> {
|
||||
public fun <R> DoubleArray.zip(other: Iterable<R>) : List<Pair<Double,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Double,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -753,9 +800,9 @@ public fun <R> DoubleArray.zip(collection: Iterable<R>) : List<Pair<Double,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> FloatArray.zip(collection: Iterable<R>) : List<Pair<Float,R>> {
|
||||
public fun <R> FloatArray.zip(other: Iterable<R>) : List<Pair<Float,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Float,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -767,9 +814,9 @@ public fun <R> FloatArray.zip(collection: Iterable<R>) : List<Pair<Float,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> IntArray.zip(collection: Iterable<R>) : List<Pair<Int,R>> {
|
||||
public fun <R> IntArray.zip(other: Iterable<R>) : List<Pair<Int,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Int,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -781,9 +828,9 @@ public fun <R> IntArray.zip(collection: Iterable<R>) : List<Pair<Int,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> LongArray.zip(collection: Iterable<R>) : List<Pair<Long,R>> {
|
||||
public fun <R> LongArray.zip(other: Iterable<R>) : List<Pair<Long,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Long,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -795,9 +842,9 @@ public fun <R> LongArray.zip(collection: Iterable<R>) : List<Pair<Long,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> ShortArray.zip(collection: Iterable<R>) : List<Pair<Short,R>> {
|
||||
public fun <R> ShortArray.zip(other: Iterable<R>) : List<Pair<Short,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Short,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -809,9 +856,9 @@ public fun <R> ShortArray.zip(collection: Iterable<R>) : List<Pair<Short,R>> {
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <T, R> Iterable<T>.zip(collection: Iterable<R>) : List<Pair<T,R>> {
|
||||
public fun <T, R> Iterable<T>.zip(other: Iterable<R>) : List<Pair<T,R>> {
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<T,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -820,6 +867,20 @@ public fun <T, R> Iterable<T>.zip(collection: Iterable<R>) : List<Pair<T,R>> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
public fun <R> String.zip(other: Iterable<R>) : List<Pair<Char,R>> {
|
||||
val first = iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Char,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
}
|
||||
return list
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream of pairs built from elements of both collections with same indexes. List has length of shortest collection.
|
||||
*/
|
||||
|
||||
@@ -84,6 +84,13 @@ public inline fun <K, V, R> Map<K,V>.flatMap(transform: (Map.Entry<K,V>)-> Itera
|
||||
return flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single list of all elements yielded from results of *transform* function being invoked on each element of original collection
|
||||
*/
|
||||
public inline fun <R> String.flatMap(transform: (Char)-> Iterable<R>) : List<R> {
|
||||
return flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single stream of all elements streamed from results of *transform* function being invoked on each element of original stream
|
||||
*/
|
||||
@@ -223,6 +230,18 @@ public inline fun <K, V, R, C: MutableCollection<in R>> Map<K,V>.flatMapTo(colle
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements yielded from results of *transform* function being invoked on each element of original collection, to the given *collection*
|
||||
*/
|
||||
public inline fun <R, C: MutableCollection<in R>> String.flatMapTo(collection: C, transform: (Char) -> Iterable<R>) : C {
|
||||
for (element in this) {
|
||||
val list = transform(element)
|
||||
collection.addAll(list)
|
||||
}
|
||||
return collection
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements yielded from results of *transform* function being invoked on each element of original stream, to the given *collection*
|
||||
*/
|
||||
@@ -319,6 +338,13 @@ public inline fun <T, K> Stream<T>.groupBy(toKey: (T) -> K) : Map<K, List<T>> {
|
||||
return groupByTo(HashMap<K, MutableList<T>>(), toKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of the elements in original collection grouped by the result of given *toKey* function
|
||||
*/
|
||||
public inline fun <K> String.groupBy(toKey: (Char) -> K) : Map<K, List<Char>> {
|
||||
return groupByTo(HashMap<K, MutableList<Char>>(), toKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends elements from original collection grouped by the result of given *toKey* function to the given *map*
|
||||
*/
|
||||
@@ -475,6 +501,19 @@ public inline fun <T, K> Stream<T>.groupByTo(map: MutableMap<K, MutableList<T>>,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends elements from original collection grouped by the result of given *toKey* function to the given *map*
|
||||
*/
|
||||
public inline fun <K> String.groupByTo(map: MutableMap<K, MutableList<Char>>, toKey: (Char) -> K) : Map<K, MutableList<Char>> {
|
||||
for (element in this) {
|
||||
val key = toKey(element)
|
||||
val list = map.getOrPut(key) { ArrayList<Char>() }
|
||||
list.add(element)
|
||||
}
|
||||
return map
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing the results of applying the given *transform* function to each element of the original collection
|
||||
*/
|
||||
@@ -559,10 +598,17 @@ public fun <T, R> Stream<T>.map(transform : (T) -> R) : Stream<R> {
|
||||
return TransformingStream(this, transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing the results of applying the given *transform* function to each element of the original collection
|
||||
*/
|
||||
public inline fun <R> String.map(transform : (Char) -> R) : List<R> {
|
||||
return mapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing the results of applying the given *transform* function to each non-null element of the original collection
|
||||
*/
|
||||
public fun <T: Any, R> Array<T?>.mapNotNull(transform : (T) -> R) : List<R> {
|
||||
public inline fun <T: Any, R> Array<T?>.mapNotNull(transform : (T) -> R) : List<R> {
|
||||
return mapNotNullTo(ArrayList<R>(), transform)
|
||||
|
||||
}
|
||||
@@ -570,7 +616,7 @@ public fun <T: Any, R> Array<T?>.mapNotNull(transform : (T) -> R) : List<R> {
|
||||
/**
|
||||
* Returns a list containing the results of applying the given *transform* function to each non-null element of the original collection
|
||||
*/
|
||||
public fun <T: Any, R> Iterable<T?>.mapNotNull(transform : (T) -> R) : List<R> {
|
||||
public inline fun <T: Any, R> Iterable<T?>.mapNotNull(transform : (T) -> R) : List<R> {
|
||||
return mapNotNullTo(ArrayList<R>(), transform)
|
||||
|
||||
}
|
||||
@@ -757,6 +803,17 @@ public inline fun <T, R, C: MutableCollection<in R>> Stream<T>.mapTo(collection:
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends transformed elements of original collection using the given *transform* function
|
||||
* to the given *collection*
|
||||
*/
|
||||
public inline fun <R, C: MutableCollection<in R>> String.mapTo(collection: C, transform : (Char) -> R) : C {
|
||||
for (item in this)
|
||||
collection.add(transform(item))
|
||||
return collection
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing pairs of each element of the original collection and their index
|
||||
*/
|
||||
@@ -856,3 +913,12 @@ public fun <T> Stream<T>.withIndices() : Stream<Pair<Int, T>> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing pairs of each element of the original collection and their index
|
||||
*/
|
||||
public fun String.withIndices() : List<Pair<Int, Char>> {
|
||||
var index = 0
|
||||
return mapTo(ArrayList<Pair<Int, Char>>(), { index++ to it })
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,14 @@ public fun <T> Iterable<T>.reverse() : List<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with characters in reversed order
|
||||
*/
|
||||
public fun String.reverse() : String {
|
||||
return StringBuilder().append(this).reverse().toString()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sorted list of all elements
|
||||
*/
|
||||
|
||||
@@ -111,6 +111,13 @@ public fun <T> Stream<T>.toArrayList() : ArrayList<T> {
|
||||
return toCollection(ArrayList<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ArrayList of all elements
|
||||
*/
|
||||
public fun String.toArrayList() : ArrayList<Char> {
|
||||
return toCollection(ArrayList<Char>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements to the given *collection*
|
||||
*/
|
||||
@@ -232,6 +239,17 @@ public fun <T, C : MutableCollection<in T>> Stream<T>.toCollection(collection :
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements to the given *collection*
|
||||
*/
|
||||
public fun <C : MutableCollection<in Char>> String.toCollection(collection : C) : C {
|
||||
for (item in this) {
|
||||
collection.add(item)
|
||||
}
|
||||
return collection
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a HashSet of all elements
|
||||
*/
|
||||
@@ -309,6 +327,13 @@ public fun <T> Stream<T>.toHashSet() : HashSet<T> {
|
||||
return toCollection(HashSet<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a HashSet of all elements
|
||||
*/
|
||||
public fun String.toHashSet() : HashSet<Char> {
|
||||
return toCollection(HashSet<Char>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a LinkedList containing all elements
|
||||
*/
|
||||
@@ -386,6 +411,13 @@ public fun <T> Stream<T>.toLinkedList() : LinkedList<T> {
|
||||
return toCollection(LinkedList<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a LinkedList containing all elements
|
||||
*/
|
||||
public fun String.toLinkedList() : LinkedList<Char> {
|
||||
return toCollection(LinkedList<Char>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List containing all elements
|
||||
*/
|
||||
@@ -487,6 +519,13 @@ public fun <T> Stream<T>.toList() : List<T> {
|
||||
return toCollection(ArrayList<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List containing all elements
|
||||
*/
|
||||
public fun String.toList() : List<Char> {
|
||||
return toCollection(ArrayList<Char>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Set of all elements
|
||||
*/
|
||||
@@ -564,6 +603,13 @@ public fun <T> Stream<T>.toSet() : Set<T> {
|
||||
return toCollection(LinkedHashSet<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Set of all elements
|
||||
*/
|
||||
public fun String.toSet() : Set<Char> {
|
||||
return toCollection(LinkedHashSet<Char>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sorted list of all elements
|
||||
*/
|
||||
@@ -641,6 +687,13 @@ public fun <T: Comparable<T>> Stream<T>.toSortedList() : List<T> {
|
||||
return toArrayList().sort()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sorted list of all elements
|
||||
*/
|
||||
public fun String.toSortedList() : List<Char> {
|
||||
return toArrayList().sort()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SortedSet of all elements
|
||||
*/
|
||||
@@ -718,3 +771,10 @@ public fun <T> Stream<T>.toSortedSet() : SortedSet<T> {
|
||||
return toCollection(TreeSet<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SortedSet of all elements
|
||||
*/
|
||||
public fun String.toSortedSet() : SortedSet<Char> {
|
||||
return toCollection(TreeSet<Char>())
|
||||
}
|
||||
|
||||
|
||||
@@ -357,6 +357,14 @@ public fun <T, R: T> Stream<T>.filterIsInstance(klass: Class<R>) : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements that are instances of specified class
|
||||
*/
|
||||
public fun <R: Char> String.filterIsInstance(klass: Class<R>) : List<R> {
|
||||
return filterIsInstanceTo(ArrayList<R>(), klass)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements that are instances of specified class into the given *collection*
|
||||
*/
|
||||
@@ -384,6 +392,15 @@ public fun <T, C: MutableCollection<in R>, R: T> Stream<T>.filterIsInstanceTo(co
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements that are instances of specified class into the given *collection*
|
||||
*/
|
||||
public fun <C: MutableCollection<in R>, R: Char> String.filterIsInstanceTo(collection: C, klass: Class<R>) : C {
|
||||
for (element in this) if (klass.isInstance(element)) collection.add(element as R)
|
||||
return collection
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts array or range in array inplace
|
||||
*/
|
||||
|
||||
@@ -95,3 +95,11 @@ public fun <T> Stream<T>.stream() : Stream<T> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream from the given collection
|
||||
*/
|
||||
public fun String.stream() : Stream<Char> {
|
||||
return object : Stream<Char> { override fun iterator() : Iterator<Char> { return this@stream.iterator() } }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -227,6 +227,26 @@ public fun <T> Stream<T>.appendString(buffer: Appendable, separator: String = ",
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string from all the elements separated using the *separator* and using the given *prefix* and *postfix* if supplied
|
||||
* If a collection could be huge you can specify a non-negative value of *limit* which will only show a subset of the collection then it will
|
||||
* a special *truncated* separator (which defaults to "..."
|
||||
*/
|
||||
public fun String.appendString(buffer: Appendable, separator: String = ", ", prefix: String ="", postfix: String = "", limit: Int = -1, truncated: String = "...") : Unit {
|
||||
buffer.append(prefix)
|
||||
var count = 0
|
||||
for (element in this) {
|
||||
if (++count > 1) buffer.append(separator)
|
||||
if (limit < 0 || count <= limit) {
|
||||
val text = if (element == null) "null" else element.toString()
|
||||
buffer.append(text)
|
||||
} else break
|
||||
}
|
||||
if (limit >= 0 && count > limit) buffer.append(truncated)
|
||||
buffer.append(postfix)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string from all the elements separated using the *separator* and using the given *prefix* and *postfix* if supplied.
|
||||
* If a collection could be huge you can specify a non-negative value of *limit* which will only show a subset of the collection then it will
|
||||
@@ -359,3 +379,15 @@ public fun <T> Stream<T>.makeString(separator: String = ", ", prefix: String = "
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string from all the elements separated using the *separator* and using the given *prefix* and *postfix* if supplied.
|
||||
* If a collection could be huge you can specify a non-negative value of *limit* which will only show a subset of the collection then it will
|
||||
* a special *truncated* separator (which defaults to "..."
|
||||
*/
|
||||
public fun String.makeString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...") : String {
|
||||
val buffer = StringBuilder()
|
||||
appendString(buffer, separator, prefix, postfix, limit, truncated)
|
||||
return buffer.toString()
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,10 @@
|
||||
package kotlin
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedList
|
||||
|
||||
/** Returns the string with leading and trailing text matching the given string removed */
|
||||
public fun String.trim(text: String) : String = trimLeading(text).trimTrailing(text)
|
||||
|
||||
/** Returns the first character */
|
||||
public fun String.first() : Char = this[0]
|
||||
|
||||
/** Returns the last character */
|
||||
public fun String.last() : Char = this[length - 1]
|
||||
public fun String.trim(text: String): String = trimLeading(text).trimTrailing(text)
|
||||
|
||||
/** Returns the string with the prefix and postfix text trimmed */
|
||||
public fun String.trim(prefix: String, postfix: String) : String = trimLeading(prefix).trimTrailing(postfix)
|
||||
public fun String.trim(prefix: String, postfix: String): String = trimLeading(prefix).trimTrailing(postfix)
|
||||
|
||||
/** Returns the string with the leading prefix of this string removed */
|
||||
public fun String.trimLeading(prefix: String): String {
|
||||
@@ -36,12 +25,12 @@ public fun String.trimTrailing(postfix: String): String {
|
||||
}
|
||||
|
||||
/** Returns true if the string is not null and not empty */
|
||||
public fun String?.isNotEmpty() : Boolean = this != null && this.length() > 0
|
||||
public fun String?.isNotEmpty(): Boolean = this != null && this.length() > 0
|
||||
|
||||
/**
|
||||
Iterator for characters of given CharSequence
|
||||
*/
|
||||
public fun CharSequence.iterator() : CharIterator = object : CharIterator() {
|
||||
* Iterator for characters of given CharSequence
|
||||
*/
|
||||
public fun CharSequence.iterator(): CharIterator = object : CharIterator() {
|
||||
private var index = 0
|
||||
|
||||
public override fun nextChar(): Char = get(index++)
|
||||
@@ -55,20 +44,27 @@ public fun String?.orEmpty(): String = this ?: ""
|
||||
|
||||
// "Extension functions" for CharSequence
|
||||
|
||||
val CharSequence.size : Int
|
||||
get() = this.length
|
||||
public val CharSequence.size: Int
|
||||
get() = this.length
|
||||
|
||||
public val String.size: Int
|
||||
get() = length()
|
||||
|
||||
public val String.indices : IntRange
|
||||
get() = 0..size
|
||||
|
||||
/**
|
||||
* Counts the number of characters which match the given predicate
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt count
|
||||
* Returns a subsequence specified by given set of indices.
|
||||
*/
|
||||
public inline fun String.count(predicate: (Char) -> Boolean): Int {
|
||||
var answer = 0
|
||||
for (c in this) {
|
||||
if (predicate(c)) {
|
||||
answer++
|
||||
}
|
||||
public fun CharSequence.slice(indices: Iterable<Int>): CharSequence {
|
||||
val result = StringBuilder()
|
||||
for (i in indices) {
|
||||
result.append(get(i))
|
||||
}
|
||||
return answer
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a substring specified by given range
|
||||
*/
|
||||
public fun String.substring(range: IntRange): String = substring(range.start, range.end + 1)
|
||||
|
||||
@@ -8,173 +8,174 @@ import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import java.nio.charset.Charset
|
||||
|
||||
public inline fun String.lastIndexOf(str: String) : Int = (this as java.lang.String).lastIndexOf(str)
|
||||
public fun String.lastIndexOf(str: String): Int = (this as java.lang.String).lastIndexOf(str)
|
||||
|
||||
public inline fun String.lastIndexOf(ch: Char) : Int = (this as java.lang.String).lastIndexOf(ch.toString())
|
||||
public fun String.lastIndexOf(ch: Char): Int = (this as java.lang.String).lastIndexOf(ch.toString())
|
||||
|
||||
public inline fun String.equalsIgnoreCase(anotherString: String) : Boolean = (this as java.lang.String).equalsIgnoreCase(anotherString)
|
||||
public fun String.equalsIgnoreCase(anotherString: String): Boolean = (this as java.lang.String).equalsIgnoreCase(anotherString)
|
||||
|
||||
public inline fun String.hashCode() : Int = (this as java.lang.String).hashCode()
|
||||
public fun String.hashCode(): Int = (this as java.lang.String).hashCode()
|
||||
|
||||
public inline fun String.indexOf(str : String) : Int = (this as java.lang.String).indexOf(str)
|
||||
public fun String.indexOf(str: String): Int = (this as java.lang.String).indexOf(str)
|
||||
|
||||
public inline fun String.indexOf(str : String, fromIndex : Int) : Int = (this as java.lang.String).indexOf(str, fromIndex)
|
||||
public fun String.indexOf(str: String, fromIndex: Int): Int = (this as java.lang.String).indexOf(str, fromIndex)
|
||||
|
||||
public inline fun String.replace(oldChar: Char, newChar : Char) : String = (this as java.lang.String).replace(oldChar, newChar)
|
||||
public fun String.replace(oldChar: Char, newChar: Char): String = (this as java.lang.String).replace(oldChar, newChar)
|
||||
|
||||
public inline fun String.replaceAll(regex: String, replacement : String) : String = (this as java.lang.String).replaceAll(regex, replacement)
|
||||
public fun String.replaceAll(regex: String, replacement: String): String = (this as java.lang.String).replaceAll(regex, replacement)
|
||||
|
||||
public inline fun String.trim() : String = (this as java.lang.String).trim()
|
||||
public fun String.trim(): String = (this as java.lang.String).trim()
|
||||
|
||||
public inline fun String.toUpperCase() : String = (this as java.lang.String).toUpperCase()
|
||||
public fun String.toUpperCase(): String = (this as java.lang.String).toUpperCase()
|
||||
|
||||
public inline fun String.toLowerCase() : String = (this as java.lang.String).toLowerCase()
|
||||
public fun String.toLowerCase(): String = (this as java.lang.String).toLowerCase()
|
||||
|
||||
public inline fun String.length() : Int = (this as java.lang.String).length()
|
||||
public fun String.length(): Int = (this as java.lang.String).length()
|
||||
|
||||
public inline fun String.getBytes() : ByteArray = (this as java.lang.String).getBytes()
|
||||
public fun String.getBytes(): ByteArray = (this as java.lang.String).getBytes()
|
||||
|
||||
public inline fun String.toCharArray() : CharArray = (this as java.lang.String).toCharArray()
|
||||
public fun String.toCharArray(): CharArray = (this as java.lang.String).toCharArray()
|
||||
|
||||
public fun String.toCharList(): List<Char> = toCharArray().toList()
|
||||
public fun String.format(vararg args: Any?): String = java.lang.String.format(this, *args)
|
||||
|
||||
public inline fun String.format(vararg args : Any?) : String = java.lang.String.format(this, *args)
|
||||
public fun String.format(locale: Locale, vararg args : Any?) : String = java.lang.String.format(locale, this, *args)
|
||||
|
||||
public inline fun String.format(locale: Locale, vararg args : Any?) : String = java.lang.String.format(locale, this, *args)
|
||||
public fun String.split(regex: String): Array<String> = (this as java.lang.String).split(regex)
|
||||
|
||||
public inline fun String.split(regex : String) : Array<String> = (this as java.lang.String).split(regex)
|
||||
public fun String.split(ch: Char): Array<String> = (this as java.lang.String).split(java.util.regex.Pattern.quote(ch.toString()))
|
||||
|
||||
public inline fun String.split(ch : Char) : Array<String> = (this as java.lang.String).split(java.util.regex.Pattern.quote(ch.toString()))
|
||||
public fun String.substring(beginIndex: Int): String = (this as java.lang.String).substring(beginIndex)
|
||||
|
||||
public inline fun String.substring(beginIndex : Int) : String = (this as java.lang.String).substring(beginIndex)
|
||||
public fun String.substring(beginIndex: Int, endIndex: Int): String = (this as java.lang.String).substring(beginIndex, endIndex)
|
||||
|
||||
public inline fun String.substring(beginIndex : Int, endIndex : Int) : String = (this as java.lang.String).substring(beginIndex, endIndex)
|
||||
public fun String.startsWith(prefix: String): Boolean = (this as java.lang.String).startsWith(prefix)
|
||||
|
||||
public inline fun String.startsWith(prefix: String) : Boolean = (this as java.lang.String).startsWith(prefix)
|
||||
public fun String.startsWith(prefix: String, toffset: Int): Boolean = (this as java.lang.String).startsWith(prefix, toffset)
|
||||
|
||||
public inline fun String.startsWith(prefix: String, toffset: Int) : Boolean = (this as java.lang.String).startsWith(prefix, toffset)
|
||||
public fun String.startsWith(ch: Char): Boolean = (this as java.lang.String).startsWith(ch.toString())
|
||||
|
||||
public inline fun String.startsWith(ch: Char) : Boolean = (this as java.lang.String).startsWith(ch.toString())
|
||||
public fun String.contains(seq: CharSequence): Boolean = (this as java.lang.String).contains(seq)
|
||||
|
||||
public inline fun String.contains(seq: CharSequence) : Boolean = (this as java.lang.String).contains(seq)
|
||||
public fun String.endsWith(suffix: String): Boolean = (this as java.lang.String).endsWith(suffix)
|
||||
|
||||
public inline fun String.endsWith(suffix: String) : Boolean = (this as java.lang.String).endsWith(suffix)
|
||||
|
||||
public inline fun String.endsWith(ch: Char) : Boolean = (this as java.lang.String).endsWith(ch.toString())
|
||||
public fun String.endsWith(ch: Char): Boolean = (this as java.lang.String).endsWith(ch.toString())
|
||||
|
||||
// "constructors" for String
|
||||
|
||||
public inline fun String(bytes : ByteArray, offset : Int, length : Int, charsetName : String) : String = java.lang.String(bytes, offset, length, charsetName) as String
|
||||
public fun String(bytes: ByteArray, offset: Int, length: Int, charsetName: String): String = java.lang.String(bytes, offset, length, charsetName) as String
|
||||
|
||||
public inline fun String(bytes : ByteArray, offset : Int, length : Int, charset : Charset) : String = java.lang.String(bytes, offset, length, charset) as String
|
||||
public fun String(bytes: ByteArray, offset: Int, length: Int, charset: Charset): String = java.lang.String(bytes, offset, length, charset) as String
|
||||
|
||||
public inline fun String(bytes : ByteArray, charsetName : String) : String = java.lang.String(bytes, charsetName) as String
|
||||
public fun String(bytes: ByteArray, charsetName: String): String = java.lang.String(bytes, charsetName) as String
|
||||
|
||||
public inline fun String(bytes : ByteArray, charset : Charset) : String = java.lang.String(bytes, charset) as String
|
||||
public fun String(bytes: ByteArray, charset: Charset): String = java.lang.String(bytes, charset) as String
|
||||
|
||||
public inline fun String(bytes : ByteArray, i : Int, i1 : Int) : String = java.lang.String(bytes, i, i1) as String
|
||||
public fun String(bytes: ByteArray, i: Int, i1: Int): String = java.lang.String(bytes, i, i1) as String
|
||||
|
||||
public inline fun String(bytes : ByteArray) : String = java.lang.String(bytes) as String
|
||||
public fun String(bytes: ByteArray): String = java.lang.String(bytes) as String
|
||||
|
||||
public inline fun String(chars : CharArray) : String = java.lang.String(chars) as String
|
||||
public fun String(chars: CharArray): String = java.lang.String(chars) as String
|
||||
|
||||
public inline fun String(stringBuffer : java.lang.StringBuffer) : String = java.lang.String(stringBuffer) as String
|
||||
public fun String(stringBuffer: java.lang.StringBuffer): String = java.lang.String(stringBuffer) as String
|
||||
|
||||
public inline fun String(stringBuilder : java.lang.StringBuilder) : String = java.lang.String(stringBuilder) as String
|
||||
public fun String(stringBuilder: java.lang.StringBuilder): String = java.lang.String(stringBuilder) as String
|
||||
|
||||
public inline fun String.replaceFirst(regex : String, replacement : String) : String = (this as java.lang.String).replaceFirst(regex, replacement)
|
||||
public fun String.replaceFirst(regex: String, replacement: String): String = (this as java.lang.String).replaceFirst(regex, replacement)
|
||||
|
||||
public inline fun String.charAt(index : Int) : Char = (this as java.lang.String).charAt(index)
|
||||
public fun String.charAt(index: Int): Char = (this as java.lang.String).charAt(index)
|
||||
|
||||
public inline fun String.split(regex : String, limit : Int) : Array<String> = (this as java.lang.String).split(regex, limit)
|
||||
public fun String.split(regex: String, limit: Int): Array<String> = (this as java.lang.String).split(regex, limit)
|
||||
|
||||
public inline fun String.codePointAt(index : Int) : Int = (this as java.lang.String).codePointAt(index)
|
||||
public fun String.codePointAt(index: Int): Int = (this as java.lang.String).codePointAt(index)
|
||||
|
||||
public inline fun String.codePointBefore(index : Int) : Int = (this as java.lang.String).codePointBefore(index)
|
||||
public fun String.codePointBefore(index: Int): Int = (this as java.lang.String).codePointBefore(index)
|
||||
|
||||
public inline fun String.codePointCount(beginIndex : Int, endIndex : Int) : Int = (this as java.lang.String).codePointCount(beginIndex, endIndex)
|
||||
public fun String.codePointCount(beginIndex: Int, endIndex: Int): Int = (this as java.lang.String).codePointCount(beginIndex, endIndex)
|
||||
|
||||
public inline fun String.compareToIgnoreCase(str : String) : Int = (this as java.lang.String).compareToIgnoreCase(str)
|
||||
public fun String.compareToIgnoreCase(str: String): Int = (this as java.lang.String).compareToIgnoreCase(str)
|
||||
|
||||
public inline fun String.concat(str : String) : String = (this as java.lang.String).concat(str)
|
||||
public fun String.concat(str: String): String = (this as java.lang.String).concat(str)
|
||||
|
||||
public inline fun String.contentEquals(cs : CharSequence) : Boolean = (this as java.lang.String).contentEquals(cs)
|
||||
public fun String.contentEquals(cs: CharSequence): Boolean = (this as java.lang.String).contentEquals(cs)
|
||||
|
||||
public inline fun String.contentEquals(sb : StringBuffer) : Boolean = (this as java.lang.String).contentEquals(sb)
|
||||
public fun String.contentEquals(sb: StringBuffer): Boolean = (this as java.lang.String).contentEquals(sb)
|
||||
|
||||
public inline fun String.getBytes(charset : Charset) : ByteArray = (this as java.lang.String).getBytes(charset)
|
||||
public fun String.getBytes(charset: Charset): ByteArray = (this as java.lang.String).getBytes(charset)
|
||||
|
||||
public inline fun String.getBytes(charsetName : String) : ByteArray = (this as java.lang.String).getBytes(charsetName)
|
||||
public fun String.getBytes(charsetName: String): ByteArray = (this as java.lang.String).getBytes(charsetName)
|
||||
|
||||
public inline fun String.getChars(srcBegin : Int, srcEnd : Int, dst : CharArray, dstBegin : Int) : Unit = (this as java.lang.String).getChars(srcBegin, srcEnd, dst, dstBegin)
|
||||
public fun String.getChars(srcBegin: Int, srcEnd: Int, dst: CharArray, dstBegin: Int): Unit = (this as java.lang.String).getChars(srcBegin, srcEnd, dst, dstBegin)
|
||||
|
||||
public inline fun String.indexOf(ch : Char) : Int = (this as java.lang.String).indexOf(ch.toString())
|
||||
public fun String.indexOf(ch: Char): Int = (this as java.lang.String).indexOf(ch.toString())
|
||||
|
||||
public inline fun String.indexOf(ch : Char, fromIndex : Int) : Int = (this as java.lang.String).indexOf(ch.toString(), fromIndex)
|
||||
public fun String.indexOf(ch: Char, fromIndex: Int): Int = (this as java.lang.String).indexOf(ch.toString(), fromIndex)
|
||||
|
||||
public inline fun String.intern() : String = (this as java.lang.String).intern()
|
||||
public fun String.intern(): String = (this as java.lang.String).intern()
|
||||
|
||||
public inline fun String.isEmpty() : Boolean = (this as java.lang.String).isEmpty()
|
||||
public fun String.isEmpty(): Boolean = (this as java.lang.String).isEmpty()
|
||||
|
||||
public inline fun String.lastIndexOf(ch : Char, fromIndex : Int) : Int = (this as java.lang.String).lastIndexOf(ch.toString(), fromIndex)
|
||||
public fun String.lastIndexOf(ch: Char, fromIndex: Int): Int = (this as java.lang.String).lastIndexOf(ch.toString(), fromIndex)
|
||||
|
||||
public inline fun String.lastIndexOf(str : String, fromIndex : Int) : Int = (this as java.lang.String).lastIndexOf(str, fromIndex)
|
||||
public fun String.lastIndexOf(str: String, fromIndex: Int): Int = (this as java.lang.String).lastIndexOf(str, fromIndex)
|
||||
|
||||
public inline fun String.matches(regex : String) : Boolean = (this as java.lang.String).matches(regex)
|
||||
public fun String.matches(regex: String): Boolean = (this as java.lang.String).matches(regex)
|
||||
|
||||
public inline fun String.offsetByCodePoints(index : Int, codePointOffset : Int) : Int = (this as java.lang.String).offsetByCodePoints(index, codePointOffset)
|
||||
public fun String.offsetByCodePoints(index: Int, codePointOffset: Int): Int = (this as java.lang.String).offsetByCodePoints(index, codePointOffset)
|
||||
|
||||
public inline fun String.regionMatches(ignoreCase : Boolean, toffset : Int, other : String, ooffset : Int, len : Int) : Boolean = (this as java.lang.String).regionMatches(ignoreCase, toffset, other, ooffset, len)
|
||||
public fun String.regionMatches(ignoreCase: Boolean, toffset: Int, other: String, ooffset: Int, len: Int): Boolean = (this as java.lang.String).regionMatches(ignoreCase, toffset, other, ooffset, len)
|
||||
|
||||
public inline fun String.regionMatches(toffset : Int, other : String, ooffset : Int, len : Int) : Boolean = (this as java.lang.String).regionMatches(toffset, other, ooffset, len)
|
||||
public fun String.regionMatches(toffset: Int, other: String, ooffset: Int, len: Int): Boolean = (this as java.lang.String).regionMatches(toffset, other, ooffset, len)
|
||||
|
||||
public inline fun String.replace(target : CharSequence, replacement : CharSequence) : String = (this as java.lang.String).replace(target, replacement)
|
||||
public fun String.replace(target: CharSequence, replacement: CharSequence): String = (this as java.lang.String).replace(target, replacement)
|
||||
|
||||
public inline fun String.subSequence(beginIndex : Int, endIndex : Int) : CharSequence = (this as java.lang.String).subSequence(beginIndex, endIndex)
|
||||
public fun String.subSequence(beginIndex: Int, endIndex: Int): CharSequence = (this as java.lang.String).subSequence(beginIndex, endIndex)
|
||||
|
||||
public inline fun String.toLowerCase(locale : java.util.Locale) : String = (this as java.lang.String).toLowerCase(locale)
|
||||
public fun String.toLowerCase(locale: java.util.Locale): String = (this as java.lang.String).toLowerCase(locale)
|
||||
|
||||
public inline fun String.toUpperCase(locale : java.util.Locale) : String = (this as java.lang.String).toUpperCase(locale)
|
||||
public fun String.toUpperCase(locale: java.util.Locale): String = (this as java.lang.String).toUpperCase(locale)
|
||||
|
||||
public fun CharSequence.charAt(index: Int): Char = (this as java.lang.CharSequence).charAt(index)
|
||||
|
||||
public inline fun CharSequence.charAt(index : Int) : Char = (this as java.lang.CharSequence).charAt(index)
|
||||
public fun CharSequence.subSequence(start: Int, end: Int): CharSequence? = (this as java.lang.CharSequence).subSequence(start, end)
|
||||
|
||||
public fun CharSequence.get(index : Int) : Char = charAt(index)
|
||||
public fun CharSequence.toString(): String? = (this as java.lang.CharSequence).toString()
|
||||
|
||||
public inline fun CharSequence.subSequence(start : Int, end : Int) : CharSequence? = (this as java.lang.CharSequence).subSequence(start, end)
|
||||
public fun CharSequence.length(): Int = (this as java.lang.CharSequence).length()
|
||||
|
||||
public fun CharSequence.get(start : Int, end : Int) : CharSequence? = subSequence(start, end)
|
||||
public fun String.toByteArray(encoding: Charset): ByteArray = (this as java.lang.String).getBytes(encoding)
|
||||
|
||||
public inline fun CharSequence.toString() : String? = (this as java.lang.CharSequence).toString()
|
||||
|
||||
public inline fun CharSequence.length() : Int = (this as java.lang.CharSequence).length()
|
||||
public fun String.toBoolean(): Boolean = java.lang.Boolean.parseBoolean(this)
|
||||
public fun String.toShort(): Short = java.lang.Short.parseShort(this)
|
||||
public fun String.toInt(): Int = java.lang.Integer.parseInt(this)
|
||||
public fun String.toLong(): Long = java.lang.Long.parseLong(this)
|
||||
public fun String.toFloat(): Float = java.lang.Float.parseFloat(this)
|
||||
public fun String.toDouble(): Double = java.lang.Double.parseDouble(this)
|
||||
|
||||
public fun String.toCharList(): List<Char> = toCharArray().toList()
|
||||
|
||||
public fun CharSequence.get(index: Int): Char = charAt(index)
|
||||
public fun CharSequence.get(start: Int, end: Int): CharSequence? = subSequence(start, end)
|
||||
public fun String.toByteArray(encoding: String = Charset.defaultCharset().name()): ByteArray = (this as java.lang.String).getBytes(encoding)
|
||||
public inline fun String.toByteArray(encoding: Charset): ByteArray = (this as java.lang.String).getBytes(encoding)
|
||||
|
||||
public inline fun String.toBoolean() : Boolean = java.lang.Boolean.parseBoolean(this)
|
||||
public inline fun String.toShort() : Short = java.lang.Short.parseShort(this)
|
||||
public inline fun String.toInt() : Int = java.lang.Integer.parseInt(this)
|
||||
public inline fun String.toLong() : Long = java.lang.Long.parseLong(this)
|
||||
public inline fun String.toFloat() : Float = java.lang.Float.parseFloat(this)
|
||||
public inline fun String.toDouble() : Double = java.lang.Double.parseDouble(this)
|
||||
/**
|
||||
* Returns a subsequence specified by given range.
|
||||
*/
|
||||
public fun CharSequence.slice(range: IntRange): CharSequence {
|
||||
return subSequence(range.start, range.end + 1)!! // inclusive
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the string into a regular expression [[Pattern]] optionally
|
||||
* with the specified flags from [[Pattern]] or'd together
|
||||
* so that strings can be split or matched on.
|
||||
*/
|
||||
public fun String.toRegex(flags: Int=0): java.util.regex.Pattern {
|
||||
public fun String.toRegex(flags: Int = 0): java.util.regex.Pattern {
|
||||
return java.util.regex.Pattern.compile(this, flags)
|
||||
}
|
||||
|
||||
val String.reader : StringReader
|
||||
get() = StringReader(this)
|
||||
|
||||
val String.size : Int
|
||||
get() = length()
|
||||
|
||||
val String.reader: StringReader
|
||||
get() = StringReader(this)
|
||||
|
||||
/**
|
||||
* Returns a copy of this string capitalised if it is not empty or already starting with an uppper case letter, otherwise returns this
|
||||
@@ -200,108 +201,23 @@ public fun String.decapitalize(): String {
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt repeat
|
||||
*/
|
||||
public fun String.repeat(n: Int): String {
|
||||
require(n >= 0, { "Cannot repeat string $n times" })
|
||||
if (n < 0)
|
||||
throw IllegalArgumentException("Value should be non-negative, but was $n")
|
||||
|
||||
var sb = StringBuilder()
|
||||
val sb = StringBuilder()
|
||||
for (i in 1..n) {
|
||||
sb.append(this)
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters characters which match the given predicate into new String object
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt filter
|
||||
*/
|
||||
public inline fun String.filter(predicate: (Char) -> Boolean): String = filterTo(StringBuilder(), predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns an Appendable containing all characters which match the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt filter
|
||||
*/
|
||||
public inline fun <T: Appendable> String.filterTo(result: T, predicate: (Char) -> Boolean): T
|
||||
{
|
||||
for (с in this) if (predicate(с)) result.append(с)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters characters which match the given predicate into new String object
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt filterNot
|
||||
*/
|
||||
public inline fun String.filterNot(predicate: (Char) -> Boolean): String = filterNotTo(StringBuilder(), predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns an Appendable containing all characters which do not match the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt filterNot
|
||||
*/
|
||||
public inline fun <T: Appendable> String.filterNotTo(result: T, predicate: (Char) -> Boolean): T {
|
||||
for (element in this) if (!predicate(element)) result.append(element)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses order of characters in a string
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt reverse
|
||||
*/
|
||||
public fun String.reverse(): String = StringBuilder(this).reverse().toString()
|
||||
|
||||
/**
|
||||
* Performs the given *operation* on each character
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt forEach
|
||||
*/
|
||||
public inline fun String.forEach(operation: (Char) -> Unit) { for(c in this) operation(c) }
|
||||
|
||||
/**
|
||||
* Returns *true* if all characters match the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt all
|
||||
*/
|
||||
public inline fun String.all(predicate: (Char) -> Boolean): Boolean {
|
||||
for(c in this) if(!predicate(c)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns *true* if any character matches the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt any
|
||||
*/
|
||||
public inline fun String.any(predicate: (Char) -> Boolean): Boolean {
|
||||
for (c in this) if (predicate(c)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string from all the characters separated using the *separator* and using the given *prefix* and *postfix* if supplied
|
||||
*
|
||||
* If a string could be huge you can specify a non-negative value of *limit* which will only show substring then it will
|
||||
* a special *truncated* separator (which defaults to "..."
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt appendString
|
||||
*/
|
||||
public fun String.appendString(buffer: Appendable, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): Unit {
|
||||
buffer.append(prefix)
|
||||
var count = 0
|
||||
for (c in this) {
|
||||
if (++count > 1) buffer.append(separator)
|
||||
if (limit < 0 || count <= limit) buffer.append(c) else break
|
||||
}
|
||||
if (limit >= 0 && count > limit) buffer.append(truncated)
|
||||
buffer.append(postfix)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first character which matches the given *predicate* or *null* if none matched
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt find
|
||||
*/
|
||||
deprecated("Use firstOrNull instead")
|
||||
public inline fun String.find(predicate: (Char) -> Boolean): Char? {
|
||||
for (c in this) if (predicate(c)) return c
|
||||
return null
|
||||
@@ -312,150 +228,18 @@ public inline fun String.find(predicate: (Char) -> Boolean): Char? {
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt findNot
|
||||
*/
|
||||
deprecated("Use firstOrNull instead")
|
||||
public inline fun String.findNot(predicate: (Char) -> Boolean): Char? {
|
||||
for (c in this) if (!predicate(c)) return c
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Partitions this string into a pair of string
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt partition
|
||||
*/
|
||||
public inline fun String.partition(predicate: (Char) -> Boolean): Pair<String, String> {
|
||||
val first = StringBuilder()
|
||||
val second = StringBuilder()
|
||||
for (c in this) {
|
||||
if (predicate(c)) {
|
||||
first.append(c)
|
||||
} else {
|
||||
second.append(c)
|
||||
}
|
||||
}
|
||||
return Pair(first.toString(), second.toString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new List containing the results of applying the given *transform* function to each character in this string
|
||||
*
|
||||
*/
|
||||
public inline fun <R> String.map(transform: (Char) -> R): List<R> = mapTo(ArrayList<R>(), transform)
|
||||
|
||||
/**
|
||||
* Transforms each character of this string with the given *transform* function and
|
||||
* adds each return value to the given *result* collection
|
||||
*
|
||||
*/
|
||||
public inline fun <R, C: MutableCollection<in R>> String.mapTo(result: C, transform: (Char) -> R): C {
|
||||
for (c in this) result.add(transform(c))
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each character to one or more values which are concatenated together into a single list
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt flatMap
|
||||
*/
|
||||
public inline fun <R> String.flatMap(transform: (Char) -> Collection<R>): Collection<R> = flatMapTo(ArrayList<R>(), transform)
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each character to one or more values which are concatenated together into a passed list
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt flatMap
|
||||
*/
|
||||
public inline fun <R> String.flatMapTo(result: MutableCollection<R>, transform: (Char) -> Collection<R>): Collection<R> {
|
||||
for (c in this) result.addAll(transform(c))
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all characters from left to right with the *initial* value to perform the operation on sequential pairs of characters
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt fold
|
||||
*/
|
||||
public inline fun <R> String.fold(initial: R, operation: (R, Char) -> R): R {
|
||||
var answer = initial
|
||||
for (c in this) answer = operation(answer, c)
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all characters from right to left with the *initial* value to perform the operation on sequential pairs of characters
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt foldRight
|
||||
*/
|
||||
public inline fun <R> String.foldRight(initial: R, operation: (Char, R) -> R): R = reverse().fold(initial, { x, y -> operation(y, x) })
|
||||
|
||||
/**
|
||||
* Applies binary operation to all characters in a string, going from left to right.
|
||||
* Similar to fold function, but uses the first character as initial value
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt reduce
|
||||
*/
|
||||
public inline fun String.reduce(operation: (Char, Char) -> Char): Char {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) {
|
||||
throw UnsupportedOperationException("Empty string can't be reduced")
|
||||
}
|
||||
|
||||
var result = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
result = operation(result, iterator.next())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies binary operation to all characters in a string, going from right to left.
|
||||
* Similar to foldRight function, but uses the last character as initial value
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt reduceRight
|
||||
*/
|
||||
public inline fun String.reduceRight(operation: (Char, Char) -> Char): Char = reverse().reduce { x, y -> operation(y, x) }
|
||||
|
||||
|
||||
/**
|
||||
* Groups the characters in the string into a new [[Map]] using the supplied *toKey* function to calculate the key to group the characters by
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt groupBy
|
||||
*/
|
||||
public inline fun <K> String.groupBy(toKey: (Char) -> K): Map<K, String> = groupByTo<K>(HashMap<K, String>(), toKey)
|
||||
|
||||
/**
|
||||
* Groups the characters in the string into the given [[Map]] using the supplied *toKey* function to calculate the key to group the characters by
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt groupBy
|
||||
*/
|
||||
public inline fun <K> String.groupByTo(result: MutableMap<K, String>, toKey: (Char) -> K): Map<K, String> {
|
||||
for (c in this) {
|
||||
val key = toKey(c)
|
||||
val str = result.getOrElse(key) { "" }
|
||||
result[key] = str + c
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new string from all the characters separated using the *separator* and using the given *prefix* and *postfix* if supplied.
|
||||
*
|
||||
* If a string could be huge you can specify a non-negative value of *limit* which will only show a substring then it will
|
||||
* a special *truncated* separator (which defaults to "..."
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt makeString
|
||||
*/
|
||||
public fun String.makeString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String {
|
||||
val buffer = StringBuilder()
|
||||
appendString(buffer, separator, prefix, postfix, limit, truncated)
|
||||
return buffer.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Appendable containing the everything but the first characters that satisfy the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt dropWhile
|
||||
*/
|
||||
public inline fun <T: Appendable> String.dropWhileTo(result: T, predicate: (Char) -> Boolean): T {
|
||||
public inline fun <T : Appendable> String.dropWhileTo(result: T, predicate: (Char) -> Boolean): T {
|
||||
var start = true
|
||||
for (element in this) {
|
||||
if (start && predicate(element)) {
|
||||
@@ -468,62 +252,20 @@ public inline fun <T: Appendable> String.dropWhileTo(result: T, predicate: (Char
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new String containing the everything but the first characters that satisfy the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt dropWhile
|
||||
*/
|
||||
public inline fun String.dropWhile(predicate: (Char) -> Boolean): String = dropWhileTo(StringBuilder(), predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns a string containing everything but the first *n* characters
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt drop
|
||||
*/
|
||||
public fun String.drop(n: Int): String = substring(Math.min(length, n))
|
||||
|
||||
/**
|
||||
* Returns an Appendable containing the first characters that satisfy the given *predicate*
|
||||
*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt takeWhile
|
||||
*/
|
||||
public inline fun <T: Appendable> String.takeWhileTo(result: T, predicate: (Char) -> Boolean): T {
|
||||
public inline fun <T : Appendable> String.takeWhileTo(result: T, predicate: (Char) -> Boolean): T {
|
||||
for (c in this) if (predicate(c)) result.append(c) else break
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new String containing the first characters that satisfy the given *predicate*
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt takeWhile
|
||||
*/
|
||||
public inline fun String.takeWhile(predicate: (Char) -> Boolean): String = takeWhileTo(StringBuilder(), predicate).toString()
|
||||
|
||||
/**
|
||||
* Returns a string containing the first *n* characters
|
||||
*
|
||||
* @includeFunctionBody ../../test/text/StringTest.kt take
|
||||
*/
|
||||
public fun String.take(n: Int): String = substring(0, Math.min(length, n))
|
||||
|
||||
/** Copies all characters into the given collection */
|
||||
public fun <C: MutableCollection<in Char>> String.toCollection(result: C): C {
|
||||
for (c in this) result.add(c)
|
||||
return result
|
||||
}
|
||||
|
||||
/** Copies all characters into a [[LinkedList]] */
|
||||
public fun String.toLinkedList(): LinkedList<Char> = toCollection(LinkedList<Char>())
|
||||
|
||||
/** Copies all characters into a [[List]] */
|
||||
public fun String.toList(): List<Char> = toCollection(ArrayList<Char>(this.length()))
|
||||
|
||||
/** Copies all characters into a [[Collection] */
|
||||
deprecated("Use toList() instead.")
|
||||
public fun String.toCollection(): Collection<Char> = toCollection(ArrayList<Char>(this.length()))
|
||||
|
||||
/** Copies all characters into a [[Set]] */
|
||||
public fun String.toSet(): Set<Char> = toCollection(HashSet<Char>())
|
||||
|
||||
/** Returns a new String containing the everything but the leading whitespace characters */
|
||||
public fun String.trimLeading(): String {
|
||||
var count = 0
|
||||
@@ -544,11 +286,11 @@ public fun String.trimTrailing(): String {
|
||||
return if (count < this.length) substring(0, count) else this
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces every *regexp* occurence in the text with the value retruned by the given function *body* that can handle
|
||||
* particular occurance using [[MatchResult]] provided.
|
||||
*/
|
||||
public fun String.replaceAll(regexp: String, body: (java.util.regex.MatchResult) -> String) : String {
|
||||
/**
|
||||
* Replaces every *regexp* occurence in the text with the value retruned by the given function *body* that can handle
|
||||
* particular occurance using [[MatchResult]] provided.
|
||||
*/
|
||||
public fun String.replaceAll(regexp: String, body: (java.util.regex.MatchResult) -> String): String {
|
||||
val sb = StringBuilder(this.length())
|
||||
val p = regexp.toRegex()
|
||||
val m = p.matcher(this)
|
||||
@@ -558,7 +300,7 @@ public fun String.replaceAll(regexp: String, body: (java.util.regex.MatchResult)
|
||||
sb.append(this, lastIdx, m.start())
|
||||
sb.append(body(m.toMatchResult()))
|
||||
lastIdx = m.end()
|
||||
}
|
||||
}
|
||||
|
||||
if (lastIdx == 0) {
|
||||
return this;
|
||||
|
||||
@@ -84,12 +84,6 @@ class StringJVMTest {
|
||||
assertEquals("abcd", "a1b2c3d4".filterNot { it.isDigit() })
|
||||
}
|
||||
|
||||
test fun reverse() {
|
||||
assertEquals("dcba", "abcd".reverse())
|
||||
assertEquals("4321", "1234".reverse())
|
||||
assertEquals("", "".reverse())
|
||||
}
|
||||
|
||||
test fun forEach() {
|
||||
val data = "abcd1234"
|
||||
var count = 0
|
||||
@@ -227,11 +221,11 @@ class StringJVMTest {
|
||||
}
|
||||
|
||||
test fun groupBy() {
|
||||
// collect similar characters by their int code
|
||||
val data = "ababaaabcd"
|
||||
val result = data.groupBy { it.toInt() }
|
||||
assertEquals(4, result.size)
|
||||
assertEquals("bbb", result.get('b'.toInt()))
|
||||
// group characters by their case
|
||||
val data = "abAbaABcD"
|
||||
val result = data.groupBy { it.isLowerCase() }
|
||||
assertEquals(2, result.size)
|
||||
assertEquals(listOf('a','b','b','a','c'), result.get(true))
|
||||
}
|
||||
|
||||
test fun makeString() {
|
||||
@@ -369,4 +363,17 @@ class StringJVMTest {
|
||||
assertEquals("", result)
|
||||
|
||||
}
|
||||
|
||||
test fun slice() {
|
||||
val iter = listOf(4, 3, 0, 1)
|
||||
|
||||
val builder = StringBuilder()
|
||||
builder.append("ABCD")
|
||||
builder.append("abcd")
|
||||
// ABCDabcd
|
||||
// 01234567
|
||||
assertEquals("BCDabc", builder.slice(1..6))
|
||||
assertEquals("baD", builder.slice(5 downTo 3))
|
||||
assertEquals("aDAB", builder.slice(iter))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +47,19 @@ class StringTest {
|
||||
assertEquals("abcd", "Abcd".decapitalize())
|
||||
assertEquals("uRL", "URL".decapitalize())
|
||||
}
|
||||
|
||||
test fun slice() {
|
||||
val iter = listOf(4, 3, 0, 1)
|
||||
// abcde
|
||||
// 01234
|
||||
assertEquals("bcd", "abcde".substring(1..3))
|
||||
assertEquals("dcb", "abcde".slice(3 downTo 1))
|
||||
assertEquals("edab", "abcde".slice(iter))
|
||||
}
|
||||
|
||||
test fun reverse() {
|
||||
assertEquals("dcba", "abcd".reverse())
|
||||
assertEquals("4321", "1234".reverse())
|
||||
assertEquals("", "".reverse())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ fun aggregates(): List<GenericFunction> {
|
||||
return count
|
||||
"""
|
||||
}
|
||||
body(Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"return size"
|
||||
}
|
||||
}
|
||||
@@ -324,7 +324,7 @@ fun aggregates(): List<GenericFunction> {
|
||||
templates add f("foldRight(initial: R, operation: (T, R) -> R)") {
|
||||
inline(true)
|
||||
|
||||
only(Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Accumulates value starting with *initial* value and applying *operation* from right to left to each element and current accumulator value" }
|
||||
typeParam("R")
|
||||
returns("R")
|
||||
@@ -363,7 +363,7 @@ fun aggregates(): List<GenericFunction> {
|
||||
templates add f("reduceRight(operation: (T, T) -> T)") {
|
||||
inline(true)
|
||||
|
||||
only(Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Accumulates value starting with last element and applying *operation* from right to left to each element and current accumulator value" }
|
||||
returns("T")
|
||||
body {
|
||||
|
||||
@@ -15,7 +15,7 @@ fun elements(): List<GenericFunction> {
|
||||
return indexOf(element) >= 0
|
||||
"""
|
||||
}
|
||||
exclude(Lists, Collections)
|
||||
exclude(Strings, Lists, Collections)
|
||||
body(ArraysOfPrimitives, ArraysOfObjects) {
|
||||
"""
|
||||
return indexOf(element) >= 0
|
||||
@@ -24,6 +24,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("indexOf(element: T)") {
|
||||
exclude(Strings)
|
||||
doc { "Returns first index of *element*, or -1 if the collection does not contain element" }
|
||||
returns("Int")
|
||||
body {
|
||||
@@ -69,6 +70,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("lastIndexOf(element: T)") {
|
||||
exclude(Strings) // has native implementation
|
||||
doc { "Returns last index of *element*, or -1 if the collection does not contain element" }
|
||||
returns("Int")
|
||||
body {
|
||||
@@ -143,7 +145,7 @@ fun elements(): List<GenericFunction> {
|
||||
throw IndexOutOfBoundsException("Collection doesn't contain element at index")
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
return get(index)
|
||||
"""
|
||||
@@ -171,7 +173,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size == 0)
|
||||
throw IllegalArgumentException("Collection is empty")
|
||||
@@ -200,7 +202,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
return if (size > 0) this[0] else null
|
||||
"""
|
||||
@@ -255,7 +257,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size == 0)
|
||||
throw IllegalArgumentException("Collection is empty")
|
||||
@@ -283,8 +285,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
include(Lists)
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
return if (size > 0) this[size - 1] else null
|
||||
"""
|
||||
@@ -348,7 +349,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size != 1)
|
||||
throw IllegalArgumentException("Collection has ${bucks}size elements")
|
||||
@@ -376,7 +377,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size == 0)
|
||||
return null
|
||||
|
||||
@@ -15,6 +15,7 @@ enum class Family {
|
||||
Maps
|
||||
ArraysOfObjects
|
||||
ArraysOfPrimitives
|
||||
Strings
|
||||
}
|
||||
|
||||
enum class PrimitiveType(val name: String) {
|
||||
@@ -30,7 +31,7 @@ enum class PrimitiveType(val name: String) {
|
||||
|
||||
|
||||
class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
val defaultFamilies = array(Iterables, Streams, ArraysOfObjects, ArraysOfPrimitives)
|
||||
val defaultFamilies = array(Iterables, Streams, ArraysOfObjects, ArraysOfPrimitives, Strings)
|
||||
|
||||
var toNullableT: Boolean = false
|
||||
|
||||
@@ -150,10 +151,12 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
Maps -> "Map<K,V>"
|
||||
Streams -> "Stream<T>"
|
||||
ArraysOfObjects -> "Array<T>"
|
||||
Strings -> "String"
|
||||
ArraysOfPrimitives -> primitive?.let { it.name() + "Array" } ?: throw IllegalArgumentException("Primitive array should specify primitive type")
|
||||
else -> throw IllegalStateException("Invalid family")
|
||||
}
|
||||
|
||||
|
||||
fun String.renderType(): String {
|
||||
val t = StringTokenizer(this, " \t\n,:()<>?.", true)
|
||||
val answer = StringBuilder()
|
||||
@@ -174,11 +177,18 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
PrimitiveType.Float -> "0.0f"
|
||||
else -> "0"
|
||||
}
|
||||
"TCollection" -> {
|
||||
when (f) {
|
||||
Strings -> "Appendable"
|
||||
else -> "MutableCollection<in T>".renderType()
|
||||
}
|
||||
}
|
||||
"T" -> {
|
||||
if (f == Maps)
|
||||
"Map.Entry<K,V>"
|
||||
else
|
||||
primitive?.name() ?: token
|
||||
when (f) {
|
||||
Strings -> "Char"
|
||||
Maps -> "Map.Entry<K,V>"
|
||||
else -> primitive?.name() ?: token
|
||||
}
|
||||
}
|
||||
else -> token
|
||||
})
|
||||
@@ -189,7 +199,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
|
||||
fun effectiveTypeParams(): List<String> {
|
||||
val types = ArrayList(typeParams)
|
||||
if (primitive == null) {
|
||||
if (primitive == null && f != Strings) {
|
||||
val implicitTypeParameters = receiver.dropWhile { it != '<' }.drop(1).takeWhile { it != '>' }.split(",")
|
||||
for (implicit in implicitTypeParameters.reverse()) {
|
||||
if (!types.any { it.startsWith(implicit) }) {
|
||||
|
||||
@@ -28,7 +28,9 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
include(Collections)
|
||||
body(Strings) { "return substring(Math.min(n, size))" }
|
||||
returns(Strings) { "String"}
|
||||
|
||||
body(Collections, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (n >= size)
|
||||
@@ -60,6 +62,9 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
body(Strings) { "return substring(0, Math.min(n, size))" }
|
||||
returns(Strings) { "String"}
|
||||
|
||||
doc(Streams) { "Returns a stream containing first *n* elements" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
body(Streams) {
|
||||
@@ -105,6 +110,17 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
for (index in 0..length)
|
||||
if (!predicate(get(index))) {
|
||||
return substring(index)
|
||||
}
|
||||
return ""
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing all elements except first elements that satisfy the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -142,6 +158,17 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
for (index in 0..length)
|
||||
if (!predicate(get(index))) {
|
||||
return substring(0, index)
|
||||
}
|
||||
return ""
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing first elements satisfying the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -163,6 +190,13 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
return filterTo(StringBuilder(), predicate).toString()
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing all elements matching the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -178,7 +212,7 @@ fun filtering(): List<GenericFunction> {
|
||||
inline(true)
|
||||
|
||||
doc { "Appends all elements matching the given *predicate* into the given *collection*" }
|
||||
typeParam("C: MutableCollection<in T>")
|
||||
typeParam("C: TCollection")
|
||||
returns("C")
|
||||
|
||||
body {
|
||||
@@ -187,6 +221,18 @@ fun filtering(): List<GenericFunction> {
|
||||
return collection
|
||||
"""
|
||||
}
|
||||
|
||||
doc(Strings) { "Appends all characters matching the given *predicate* to the given *collection*" }
|
||||
body(Strings) {
|
||||
"""
|
||||
for (index in 0..length - 1) {
|
||||
val element = get(index)
|
||||
if (predicate(element)) destination.append(element)
|
||||
}
|
||||
return destination
|
||||
"""
|
||||
}
|
||||
|
||||
include(Maps)
|
||||
}
|
||||
|
||||
@@ -201,6 +247,13 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
return filterNotTo(StringBuilder(), predicate).toString()
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing all elements not matching the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -216,7 +269,7 @@ fun filtering(): List<GenericFunction> {
|
||||
inline(true)
|
||||
|
||||
doc { "Appends all elements not matching the given *predicate* to the given *collection*" }
|
||||
typeParam("C: MutableCollection<in T>")
|
||||
typeParam("C: TCollection")
|
||||
returns("C")
|
||||
|
||||
body {
|
||||
@@ -225,11 +278,19 @@ fun filtering(): List<GenericFunction> {
|
||||
return collection
|
||||
"""
|
||||
}
|
||||
|
||||
doc(Strings) { "Appends all characters not matching the given *predicate* to the given *collection*" }
|
||||
body(Strings) {
|
||||
"""
|
||||
for (element in this) if (!predicate(element)) collection.append(element)
|
||||
return collection
|
||||
"""
|
||||
}
|
||||
include(Maps)
|
||||
}
|
||||
|
||||
templates add f("filterNotNull()") {
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(ArraysOfPrimitives, Strings)
|
||||
doc { "Returns a list containing all elements that are not null" }
|
||||
typeParam("T: Any")
|
||||
returns("List<T>")
|
||||
@@ -250,11 +311,11 @@ fun filtering(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("filterNotNullTo(collection: C)") {
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(ArraysOfPrimitives, Strings)
|
||||
doc { "Appends all elements that are not null to the given *collection*" }
|
||||
typeParam("C: MutableCollection<in T>")
|
||||
typeParam("T: Any")
|
||||
returns("C")
|
||||
typeParam("C: TCollection")
|
||||
typeParam("T: Any")
|
||||
toNullableT = true
|
||||
body {
|
||||
"""
|
||||
@@ -265,7 +326,7 @@ fun filtering(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("slice(indices: Iterable<Int>)") {
|
||||
only(Lists, ArraysOfPrimitives, ArraysOfObjects)
|
||||
only(Strings, Lists, ArraysOfPrimitives, ArraysOfObjects)
|
||||
doc { "Returns a list containing elements at specified positions" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -277,6 +338,17 @@ fun filtering(): List<GenericFunction> {
|
||||
return list
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String" }
|
||||
body(Strings) {
|
||||
"""
|
||||
val result = StringBuilder()
|
||||
for (i in indices) {
|
||||
result.append(get(i))
|
||||
}
|
||||
return result.toString()
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
return templates
|
||||
|
||||
@@ -6,6 +6,7 @@ fun generators(): List<GenericFunction> {
|
||||
val templates = arrayListOf<GenericFunction>()
|
||||
|
||||
templates add f("plus(element: T)") {
|
||||
exclude(Strings)
|
||||
doc { "Returns a list containing all elements of original collection and then the given element" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -26,7 +27,7 @@ fun generators(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("plus(collection: Iterable<T>)") {
|
||||
exclude(Streams)
|
||||
exclude(Strings, Streams)
|
||||
doc { "Returns a list containing all elements of original collection and then all elements of the given *collection*" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -39,7 +40,7 @@ fun generators(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("plus(array: Array<T>)") {
|
||||
exclude(Streams)
|
||||
exclude(Strings, Streams)
|
||||
doc { "Returns a list containing all elements of original collection and then all elements of the given *collection*" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -99,9 +100,25 @@ fun generators(): List<GenericFunction> {
|
||||
return Pair(first, second)
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "Pair<String, String>" }
|
||||
body(Strings) {
|
||||
"""
|
||||
val first = StringBuilder()
|
||||
val second = StringBuilder()
|
||||
for (element in this) {
|
||||
if (predicate(element)) {
|
||||
first.append(element)
|
||||
} else {
|
||||
second.append(element)
|
||||
}
|
||||
}
|
||||
return Pair(first.toString(), second.toString())
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("zip(collection: Iterable<R>)") {
|
||||
templates add f("zip(other: Iterable<R>)") {
|
||||
exclude(Streams)
|
||||
doc {
|
||||
"""
|
||||
@@ -113,7 +130,7 @@ fun generators(): List<GenericFunction> {
|
||||
body {
|
||||
"""
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<T,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -123,6 +140,27 @@ fun generators(): List<GenericFunction> {
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("zip(other : String)") {
|
||||
only(Strings)
|
||||
doc {
|
||||
"""
|
||||
Returns a list of pairs built from characters of both strings with same indexes. List has length of shortest collection.
|
||||
"""
|
||||
}
|
||||
returns("List<Pair<Char,Char>>")
|
||||
body {
|
||||
"""
|
||||
val first = iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Char,Char>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
}
|
||||
return list
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("zip(array: Array<R>)") {
|
||||
exclude(Streams)
|
||||
doc {
|
||||
|
||||
@@ -10,7 +10,7 @@ fun guards(): List<GenericFunction> {
|
||||
|
||||
templates add f("requireNoNulls()") {
|
||||
include(Lists)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings, ArraysOfPrimitives)
|
||||
doc { "Returns an original collection containing all the non-*null* elements, throwing an [[IllegalArgumentException]] if there are any null elements" }
|
||||
typeParam("T:Any")
|
||||
toNullableT = true
|
||||
|
||||
@@ -45,7 +45,8 @@ fun mapping(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("mapNotNull(transform : (T) -> R)") {
|
||||
exclude(ArraysOfPrimitives)
|
||||
inline(true)
|
||||
exclude(Strings, ArraysOfPrimitives)
|
||||
doc { "Returns a list containing the results of applying the given *transform* function to each non-null element of the original collection" }
|
||||
typeParam("T: Any")
|
||||
typeParam("R")
|
||||
@@ -59,6 +60,7 @@ fun mapping(): List<GenericFunction> {
|
||||
|
||||
doc(Streams) { "Returns a stream containing the results of applying the given *transform* function to each non-null element of the original stream" }
|
||||
returns(Streams) { "Stream<R>" }
|
||||
inline(false, Streams)
|
||||
body(Streams) {
|
||||
"""
|
||||
return TransformingStream(FilteringStream(this, false, { it != null }) as Stream<T>, transform)
|
||||
@@ -91,7 +93,7 @@ fun mapping(): List<GenericFunction> {
|
||||
|
||||
templates add f("mapNotNullTo(collection: C, transform : (T) -> R)") {
|
||||
inline(true)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings, ArraysOfPrimitives)
|
||||
doc {
|
||||
"""
|
||||
Appends transformed non-null elements of original collection using the given *transform* function
|
||||
|
||||
@@ -16,6 +16,15 @@ fun ordering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
doc(Strings) { "Returns a string with characters in reversed order" }
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
// TODO: Replace with StringBuilder(this) when JS can handle it
|
||||
"""
|
||||
return StringBuilder().append(this).reverse().toString()
|
||||
"""
|
||||
}
|
||||
|
||||
exclude(Streams)
|
||||
}
|
||||
|
||||
@@ -38,6 +47,7 @@ fun ordering(): List<GenericFunction> {
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives) // TODO: resolve collision between inplace sort and this function
|
||||
exclude(ArraysOfObjects)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortDescending()") {
|
||||
@@ -60,6 +70,7 @@ fun ordering(): List<GenericFunction> {
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives) // TODO: resolve collision between inplace sort and this function
|
||||
exclude(ArraysOfObjects)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortBy(order: (T) -> R)") {
|
||||
@@ -83,6 +94,7 @@ fun ordering(): List<GenericFunction> {
|
||||
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortDescendingBy(order: (T) -> R)") {
|
||||
@@ -106,6 +118,7 @@ fun ordering(): List<GenericFunction> {
|
||||
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortBy(comparator : Comparator<T>)") {
|
||||
@@ -125,6 +138,7 @@ fun ordering(): List<GenericFunction> {
|
||||
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
return templates
|
||||
|
||||
Reference in New Issue
Block a user