diff --git a/libraries/stdlib/src/generated/_Strings.kt b/libraries/stdlib/src/generated/_Strings.kt index dc2ced5acea..6b059681ef5 100644 --- a/libraries/stdlib/src/generated/_Strings.kt +++ b/libraries/stdlib/src/generated/_Strings.kt @@ -15,13 +15,13 @@ import java.util.Collections // TODO: it's temporary while we have java.util.Col * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Array.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun Array.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): A { 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() + val text = if (transform != null) transform(element) else if (element == null) "null" else element.toString() buffer.append(text) } else break } @@ -35,13 +35,13 @@ public fun Array.joinTo(buffer: A, separator: String * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun BooleanArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun BooleanArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Boolean) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -55,13 +55,13 @@ public fun BooleanArray.joinTo(buffer: A, separator: String = " * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun ByteArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun ByteArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Byte) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -75,13 +75,13 @@ public fun ByteArray.joinTo(buffer: A, separator: String = ", " * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun CharArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun CharArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Char) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -95,13 +95,13 @@ public fun CharArray.joinTo(buffer: A, separator: String = ", " * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun DoubleArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun DoubleArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Double) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -115,13 +115,13 @@ public fun DoubleArray.joinTo(buffer: A, separator: String = ", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun FloatArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun FloatArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Float) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -135,13 +135,13 @@ public fun FloatArray.joinTo(buffer: A, separator: String = ", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun IntArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun IntArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Int) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -155,13 +155,13 @@ public fun IntArray.joinTo(buffer: A, separator: String = ", ", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun LongArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun LongArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Long) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -175,13 +175,13 @@ public fun LongArray.joinTo(buffer: A, separator: String = ", " * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun ShortArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun ShortArray.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Short) -> String)? = null): A { buffer.append(prefix) var count = 0 for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -195,13 +195,13 @@ public fun ShortArray.joinTo(buffer: A, separator: String = ", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Iterable.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun Iterable.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): A { 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() + val text = if (transform != null) transform(element) else if (element == null) "null" else element.toString() buffer.append(text) } else break } @@ -215,13 +215,13 @@ public fun Iterable.joinTo(buffer: A, separator: String = * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Sequence.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun Sequence.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): A { 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() + val text = if (transform != null) transform(element) else if (element == null) "null" else element.toString() buffer.append(text) } else break } @@ -237,13 +237,13 @@ deprecated("Migrate to using Sequence and respective functions") * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Stream.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): A { +public fun Stream.joinTo(buffer: A, separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): A { 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() + val text = if (transform != null) transform(element) else if (element == null) "null" else element.toString() buffer.append(text) } else break } @@ -257,8 +257,8 @@ public fun Stream.joinTo(buffer: A, separator: String = " * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Array.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun Array.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -266,8 +266,8 @@ public fun Array.joinToString(separator: String = ", ", prefix: Strin * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun BooleanArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun BooleanArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Boolean) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -275,8 +275,8 @@ public fun BooleanArray.joinToString(separator: String = ", ", prefix: String = * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun ByteArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun ByteArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Byte) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -284,8 +284,8 @@ public fun ByteArray.joinToString(separator: String = ", ", prefix: String = "", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun CharArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun CharArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Char) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -293,8 +293,8 @@ public fun CharArray.joinToString(separator: String = ", ", prefix: String = "", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun DoubleArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun DoubleArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Double) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -302,8 +302,8 @@ public fun DoubleArray.joinToString(separator: String = ", ", prefix: String = " * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun FloatArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun FloatArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Float) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -311,8 +311,8 @@ public fun FloatArray.joinToString(separator: String = ", ", prefix: String = "" * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun IntArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun IntArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Int) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -320,8 +320,8 @@ public fun IntArray.joinToString(separator: String = ", ", prefix: String = "", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun LongArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun LongArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Long) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -329,8 +329,8 @@ public fun LongArray.joinToString(separator: String = ", ", prefix: String = "", * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun ShortArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun ShortArray.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Short) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -338,8 +338,8 @@ public fun ShortArray.joinToString(separator: String = ", ", prefix: String = "" * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Iterable.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun Iterable.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } /** @@ -347,8 +347,8 @@ public fun Iterable.joinToString(separator: String = ", ", prefix: String * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Sequence.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun Sequence.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } @@ -358,7 +358,7 @@ deprecated("Migrate to using Sequence and respective functions") * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). */ -public fun Stream.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "..."): String { - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() +public fun Stream.joinToString(separator: String = ", ", prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((T) -> String)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() } diff --git a/libraries/stdlib/test/collections/IterableTests.kt b/libraries/stdlib/test/collections/IterableTests.kt index 8bb76c8163e..1eac9153059 100644 --- a/libraries/stdlib/test/collections/IterableTests.kt +++ b/libraries/stdlib/test/collections/IterableTests.kt @@ -267,4 +267,10 @@ abstract class IterableTests>(val data: T, val empty: T) { assertEquals(6, reduced.length()) assertTrue(reduced == "foobar" || reduced == "barfoo") } + + Test + fun mapAndJoinToString() { + val result = data.joinToString(separator = "-") { it.toUpperCase() } + assertEquals("FOO-BAR", result) + } } diff --git a/libraries/stdlib/test/collections/SequenceTest.kt b/libraries/stdlib/test/collections/SequenceTest.kt index 1b09f563d0c..f1d9bba76c9 100644 --- a/libraries/stdlib/test/collections/SequenceTest.kt +++ b/libraries/stdlib/test/collections/SequenceTest.kt @@ -73,6 +73,10 @@ public class SequenceTest { } } + test fun mapAndJoinToString() { + assertEquals("3, 5, 8", fibonacci().withIndex().filter { it.index > 3 }.take(3).joinToString { it.value.toString() }) + } + test fun withIndex() { val data = sequenceOf("foo", "bar") val indexed = data.withIndex().map { it.value.substring(0..it.index) }.toList() diff --git a/libraries/stdlib/test/text/StringJVMTest.kt b/libraries/stdlib/test/text/StringJVMTest.kt index f88170017e9..4617c959576 100644 --- a/libraries/stdlib/test/text/StringJVMTest.kt +++ b/libraries/stdlib/test/text/StringJVMTest.kt @@ -240,6 +240,10 @@ class StringJVMTest { val data2 = "verylongstring".toList() val result2 = data2.joinToString("-", "[", "]", 11, "oops") assertEquals("[v-e-r-y-l-o-n-g-s-t-r-oops]", result2) + + val data3 = "a1/b".toList() + val result3 = data3.joinToString() { it.toUpperCase().toString() } + assertEquals("A, 1, /, B", result3) } test fun join() { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt index fee3eadf543..dd1fdeb8902 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt @@ -5,7 +5,7 @@ import templates.Family.* fun strings(): List { val templates = arrayListOf() - templates add f("joinTo(buffer: A, separator: String = \", \", prefix: String = \"\", postfix: String = \"\", limit: Int = -1, truncated: String = \"...\")") { + templates add f("joinTo(buffer: A, separator: String = \", \", prefix: String = \"\", postfix: String = \"\", limit: Int = -1, truncated: String = \"...\", transform: ((T) -> String)? = null)") { doc { """ Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. @@ -23,7 +23,7 @@ fun strings(): List { for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = if (element == null) "null" else element.toString() + val text = if (transform != null) transform(element) else if (element == null) "null" else element.toString() buffer.append(text) } else break } @@ -40,7 +40,7 @@ fun strings(): List { for (element in this) { if (++count > 1) buffer.append(separator) if (limit < 0 || count <= limit) { - val text = element.toString() + val text = if (transform != null) transform(element) else element.toString() buffer.append(text) } else break } @@ -51,7 +51,7 @@ fun strings(): List { } } - templates add f("joinToString(separator: String = \", \", prefix: String = \"\", postfix: String = \"\", limit: Int = -1, truncated: String = \"...\")") { + templates add f("joinToString(separator: String = \", \", prefix: String = \"\", postfix: String = \"\", limit: Int = -1, truncated: String = \"...\", transform: ((T) -> String)? = null)") { doc { """ Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. @@ -65,7 +65,7 @@ fun strings(): List { returns("String") body { """ - return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated).toString() + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() """ } }