From 4c58f4ec2013afa43b7771fbccfca135d0c44d01 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Thu, 19 Mar 2015 15:38:24 +0300 Subject: [PATCH] Add removeRange method. Breaking change in replaceRange(IntRange, String) method: the end index of the range now is included in the part being replaced. --- libraries/stdlib/src/kotlin/text/Strings.kt | 35 ++++++++++++++++----- libraries/stdlib/test/text/StringTest.kt | 20 +++++++++++- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/libraries/stdlib/src/kotlin/text/Strings.kt b/libraries/stdlib/src/kotlin/text/Strings.kt index cce8ec7a123..cb28cb4fa12 100644 --- a/libraries/stdlib/src/kotlin/text/Strings.kt +++ b/libraries/stdlib/src/kotlin/text/Strings.kt @@ -308,17 +308,38 @@ public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: Str /** * Replace the part of string at the given [range] with the [replacement] string. + * + * The end index of the [range] is included in the part to be replaced. */ -public fun String.replaceRange(range: IntRange, replacement: String): String { - if (range.end < range.start) - throw IndexOutOfBoundsException("Last index (${range.start}) is less than first index (${range.end})") - val sb = StringBuilder() - sb.append(this, 0, range.start) - sb.append(replacement) - sb.append(this, range.end, length) +public fun String.replaceRange(range: IntRange, replacement: String): String = replaceRange(range.start, range.end + 1, replacement) + +/** + * Removes the part of a string at a given range. + * @param firstIndex the index of the first character to be removed. + * @param lastIndex the index of the first character after the removed part to keep in the string. +* +* [lastIndex] is not included in the removed part. + */ +public fun String.removeRange(firstIndex: Int, lastIndex: Int): String { + if (lastIndex < firstIndex) + throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)") + + if (lastIndex == firstIndex) + return this + + val sb = StringBuilder(length() - (lastIndex - firstIndex)) + sb.append(this, 0, firstIndex) + sb.append(this, lastIndex, length()) return sb.toString() } +/** + * Removes the part of a string at the given [range]. + * + * The end index of the [range] is included in the removed part. + */ +public fun String.removeRange(range: IntRange): String = removeRange(range.start, range.end + 1) + /** * Replace part of string before the first occurrence of given delimiter with the [replacement] string. * If the string does not contain the delimiter, returns [missingDelimiterValue] which defaults to the original string. diff --git a/libraries/stdlib/test/text/StringTest.kt b/libraries/stdlib/test/text/StringTest.kt index 9f520fbd8f6..2b6025b7af0 100644 --- a/libraries/stdlib/test/text/StringTest.kt +++ b/libraries/stdlib/test/text/StringTest.kt @@ -72,13 +72,31 @@ class StringTest { test fun replaceRange() { val s = "sample text" assertEquals("sa??e text", s.replaceRange(2, 5, "??")) - assertEquals("sa??e text", s.replaceRange(2..5, "??")) + assertEquals("sa?? text", s.replaceRange(2..5, "??")) fails { s.replaceRange(5..2, "??") } fails { s.replaceRange(5, 2, "??") } + + // symmetry with indices + assertEquals("??", s.replaceRange(s.indices, "??")) + } + + test fun removeRange() { + val s = "sample text" + assertEquals("sae text", s.removeRange(2, 5)) + assertEquals("sa text", s.removeRange(2..5)) + + assertEquals(s, s.removeRange(2,2)) + + // symmetry with indices + assertEquals("", s.removeRange(s.indices)) + + // symmetry with replaceRange + assertEquals(s.replaceRange(2, 5, ""), s.removeRange(2, 5)) + assertEquals(s.replaceRange(2..5, ""), s.removeRange(2..5)) } test fun substringDelimited() {