From 9b17220baa0cf1b2d6157a59bc0670fb7e728732 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Mon, 1 Jun 2015 16:17:08 +0300 Subject: [PATCH] Provide dropLastWhile for Arrays, Lists and Strings. --- libraries/stdlib/src/generated/_Filtering.kt | 133 +++++++++++++++++- .../stdlib/test/collections/CollectionTest.kt | 8 ++ .../src/templates/Filtering.kt | 32 ++++- 3 files changed, 163 insertions(+), 10 deletions(-) diff --git a/libraries/stdlib/src/generated/_Filtering.kt b/libraries/stdlib/src/generated/_Filtering.kt index a3541f57557..23c3a418d07 100644 --- a/libraries/stdlib/src/generated/_Filtering.kt +++ b/libraries/stdlib/src/generated/_Filtering.kt @@ -189,6 +189,133 @@ public fun String.drop(n: Int): String { return substring(Math.min(n, length())) } +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun Array.dropLastWhile(predicate: (T) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun BooleanArray.dropLastWhile(predicate: (Boolean) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun ByteArray.dropLastWhile(predicate: (Byte) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun CharArray.dropLastWhile(predicate: (Char) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun DoubleArray.dropLastWhile(predicate: (Double) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun FloatArray.dropLastWhile(predicate: (Float) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun IntArray.dropLastWhile(predicate: (Int) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun LongArray.dropLastWhile(predicate: (Long) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun ShortArray.dropLastWhile(predicate: (Short) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +public inline fun List.dropLastWhile(predicate: (T) -> Boolean): List { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() +} + +/** + * Returns a string containing all characters except last characters that satisfy the given [predicate]. + */ +public inline fun String.dropLastWhile(predicate: (Char) -> Boolean): String { + return trimEnd(predicate) +} + /** * Returns a list containing all elements except first elements that satisfy the given [predicate]. */ @@ -369,11 +496,7 @@ public fun Stream.dropWhile(predicate: (T) -> Boolean): Stream { * Returns a string containing all characters except first characters that satisfy the given [predicate]. */ public inline fun String.dropWhile(predicate: (Char) -> Boolean): String { - for (index in 0..length - 1) - if (!predicate(get(index))) { - return substring(index) - } - return "" + return trimStart(predicate) } /** diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index e81962a043c..9d34f3c3fc9 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -273,6 +273,14 @@ class CollectionTest { assertEquals(listOf("bar", "abc"), coll.dropWhile { it.startsWith("f") }) } + test fun dropLastWhile() { + val coll = listOf("Foo", "bare", "abc" ) + assertEquals(coll, coll.dropLastWhile { false }) + assertEquals(listOf(), coll.dropLastWhile { true }) + assertEquals(listOf("Foo", "bare"), coll.dropLastWhile { it.length() < 4 }) + assertEquals(listOf("Foo"), coll.dropLastWhile { it.all { it in 'a'..'z' } }) + } + test fun take() { val coll = listOf("foo", "bar", "abc") assertEquals(listOf("foo"), coll.take(1)) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt index f6b10ecd454..fb9b9980279 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt @@ -170,11 +170,7 @@ fun filtering(): List { returns(Strings) { "String" } body(Strings) { """ - for (index in 0..length - 1) - if (!predicate(get(index))) { - return substring(index) - } - return "" + return trimStart(predicate) """ } @@ -228,6 +224,32 @@ fun filtering(): List { } } + templates add f("dropLastWhile(predicate: (T) -> Boolean)") { + inline(true) + only(Lists, ArraysOfObjects, ArraysOfPrimitives, Strings) + doc { "Returns a list containing all elements except last elements that satisfy the given [predicate]." } + returns("List") + + body { + """ + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return take(index + 1) + } + } + return emptyList() + """ + } + + doc(Strings) { "Returns a string containing all characters except last characters that satisfy the given [predicate]." } + returns("String", Strings) + body(Strings) { + """ + return trimEnd(predicate) + """ + } + } + templates add f("filter(predicate: (T) -> Boolean)") { inline(true)