indexOfAny, lastIndexOfAny return an index value only (similar to indexOf, lastIndexOf).
findAnyOf, findLastAnyOf introduced to cover the case when an index and a matched string value is required.
This commit is contained in:
@@ -491,8 +491,7 @@ public fun String.endsWith(char: Char): Boolean = endsWith(char, ignoreCase = fa
|
||||
|
||||
// indexOfAny()
|
||||
|
||||
|
||||
private fun String.indexOfAny(chars: CharArray, startIndex: Int, ignoreCase: Boolean, last: Boolean): Pair<Int, Char>? {
|
||||
private fun String.findAnyOf(chars: CharArray, startIndex: Int, ignoreCase: Boolean, last: Boolean): Pair<Int, Char>? {
|
||||
if (!ignoreCase && chars.size() == 1) {
|
||||
val char = chars.single()
|
||||
val index = if (!last) nativeIndexOf(char, startIndex) else nativeLastIndexOf(char, startIndex)
|
||||
@@ -511,31 +510,31 @@ private fun String.indexOfAny(chars: CharArray, startIndex: Int, ignoreCase: Boo
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first occurrence of any of the specified [chars] in this string, starting from the specified [startIndex] and
|
||||
* Finds the index of the first occurrence of any of the specified [chars] in this string, starting from the specified [startIndex] and
|
||||
* optionally ignoring the case.
|
||||
*
|
||||
* @param ignoreCase `true` to ignore character case when matching a character. By default `false`.
|
||||
* @returns A pair of an index of the first occurrence of matched character from [chars] and the character matched or `null` if none of [chars] are found.
|
||||
* @returns An index of the first occurrence of matched character from [chars] or -1 if none of [chars] are found.
|
||||
*
|
||||
*/
|
||||
public fun String.indexOfAny(chars: CharArray, startIndex: Int = 0, ignoreCase: Boolean = false): Pair<Int, Char>? =
|
||||
indexOfAny(chars, startIndex, ignoreCase, last = false)
|
||||
public fun String.indexOfAny(chars: CharArray, startIndex: Int = 0, ignoreCase: Boolean = false): Int =
|
||||
findAnyOf(chars, startIndex, ignoreCase, last = false)?.first ?: -1
|
||||
|
||||
/**
|
||||
* Finds the last occurrence of any of the specified [chars] in this string, starting from the specified [startIndex] and
|
||||
* Finds the index of the last occurrence of any of the specified [chars] in this string, starting from the specified [startIndex] and
|
||||
* optionally ignoring the case.
|
||||
*
|
||||
* @param startIndex The index of character to start searching at. The search proceeds backward toward the beginning of the string.
|
||||
* @param ignoreCase `true` to ignore character case when matching a character. By default `false`.
|
||||
* @returns A pair of an index of the last occurrence of matched character from [chars] and the character matched or `null` if none of [chars] are found.
|
||||
* @returns An index of the last occurrence of matched character from [chars] or -1 if none of [chars] are found.
|
||||
*
|
||||
*/
|
||||
public fun String.lastIndexOfAny(chars: CharArray, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Pair<Int, Char>? =
|
||||
indexOfAny(chars, startIndex, ignoreCase, last = true)
|
||||
public fun String.lastIndexOfAny(chars: CharArray, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Int =
|
||||
findAnyOf(chars, startIndex, ignoreCase, last = true)?.first ?: -1
|
||||
|
||||
|
||||
|
||||
private fun String.indexOfAny(strings: Collection<String>, startIndex: Int, ignoreCase: Boolean, last: Boolean): Pair<Int, String>? {
|
||||
private fun String.findAnyOf(strings: Collection<String>, startIndex: Int, ignoreCase: Boolean, last: Boolean): Pair<Int, String>? {
|
||||
if (!ignoreCase && strings.size() == 1) {
|
||||
val string = strings.single()
|
||||
val index = if (!last) nativeIndexOf(string, startIndex) else nativeLastIndexOf(string, startIndex)
|
||||
@@ -557,14 +556,14 @@ private fun String.indexOfAny(strings: Collection<String>, startIndex: Int, igno
|
||||
* optionally ignoring the case.
|
||||
*
|
||||
* @param ignoreCase `true` to ignore character case when matching a string. By default `false`.
|
||||
* @returns A pair of an index of the first occurrence of matched string from [stromgs] and the string matched or `null` if none of [strings] are found.
|
||||
* @returns A pair of an index of the first occurrence of matched string from [strings] and the string matched or `null` if none of [strings] are found.
|
||||
*
|
||||
* To avoid ambiguous results when strings in [strings] have characters in common, this method proceeds from
|
||||
* the beginning to the end of this string, and finds at each position the first element in [strings]
|
||||
* that matches this string at that position.
|
||||
*/
|
||||
public fun String.indexOfAny(strings: Collection<String>, startIndex: Int = 0, ignoreCase: Boolean = false): Pair<Int, String>? =
|
||||
indexOfAny(strings, startIndex, ignoreCase, last = false)
|
||||
public fun String.findAnyOf(strings: Collection<String>, startIndex: Int = 0, ignoreCase: Boolean = false): Pair<Int, String>? =
|
||||
findAnyOf(strings, startIndex, ignoreCase, last = false)
|
||||
|
||||
/**
|
||||
* Finds the last occurrence of any of the specified [strings] in this string, starting from the specified [startIndex] and
|
||||
@@ -578,8 +577,37 @@ public fun String.indexOfAny(strings: Collection<String>, startIndex: Int = 0, i
|
||||
* the end toward the beginning of this string, and finds at each position the first element in [strings]
|
||||
* that matches this string at that position.
|
||||
*/
|
||||
public fun String.lastIndexOfAny(strings: Collection<String>, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Pair<Int, String>? =
|
||||
indexOfAny(strings, startIndex, ignoreCase, last = true)
|
||||
public fun String.findLastAnyOf(strings: Collection<String>, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Pair<Int, String>? =
|
||||
findAnyOf(strings, startIndex, ignoreCase, last = true)
|
||||
|
||||
/**
|
||||
* Finds the index of the first occurrence of any of the specified [strings] in this string, starting from the specified [startIndex] and
|
||||
* optionally ignoring the case.
|
||||
*
|
||||
* @param ignoreCase `true` to ignore character case when matching a string. By default `false`.
|
||||
* @returns An index of the first occurrence of matched string from [strings] or -1 if none of [strings] are found.
|
||||
*
|
||||
* To avoid ambiguous results when strings in [strings] have characters in common, this method proceeds from
|
||||
* the beginning to the end of this string, and finds at each position the first element in [strings]
|
||||
* that matches this string at that position.
|
||||
*/
|
||||
public fun String.indexOfAny(strings: Collection<String>, startIndex: Int = 0, ignoreCase: Boolean = false): Int =
|
||||
findAnyOf(strings, startIndex, ignoreCase, last = false)?.first ?: -1
|
||||
|
||||
/**
|
||||
* Finds the index of the last occurrence of any of the specified [strings] in this string, starting from the specified [startIndex] and
|
||||
* optionally ignoring the case.
|
||||
*
|
||||
* @param startIndex The index of character to start searching at. The search proceeds backward toward the beginning of the string.
|
||||
* @param ignoreCase `true` to ignore character case when matching a string. By default `false`.
|
||||
* @returns An index of the last occurrence of matched string from [strings] or -1 if none of [strings] are found.
|
||||
*
|
||||
* To avoid ambiguous results when strings in [strings] have characters in common, this method proceeds from
|
||||
* the end toward the beginning of this string, and finds at each position the first element in [strings]
|
||||
* that matches this string at that position.
|
||||
*/
|
||||
public fun String.lastIndexOfAny(strings: Collection<String>, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Int =
|
||||
findAnyOf(strings, startIndex, ignoreCase, last = true)?.first ?: -1
|
||||
|
||||
|
||||
// indexOf
|
||||
@@ -592,7 +620,7 @@ public fun String.lastIndexOfAny(strings: Collection<String>, startIndex: Int =
|
||||
*/
|
||||
public fun String.indexOf(char: Char, startIndex: Int = 0, ignoreCase: Boolean = false): Int {
|
||||
return if (ignoreCase)
|
||||
indexOfAny(charArray(char), startIndex, ignoreCase)?.first ?: -1
|
||||
indexOfAny(charArray(char), startIndex, ignoreCase)
|
||||
else
|
||||
nativeIndexOf(char, startIndex)
|
||||
}
|
||||
@@ -605,7 +633,7 @@ public fun String.indexOf(char: Char, startIndex: Int = 0, ignoreCase: Boolean =
|
||||
*/
|
||||
public fun String.indexOf(string: String, startIndex: Int = 0, ignoreCase: Boolean = false): Int {
|
||||
return if (ignoreCase)
|
||||
indexOfAny(listOf(string), startIndex, ignoreCase)?.first ?: -1
|
||||
indexOfAny(listOf(string), startIndex, ignoreCase)
|
||||
else
|
||||
nativeIndexOf(string, startIndex)
|
||||
}
|
||||
@@ -619,7 +647,7 @@ public fun String.indexOf(string: String, startIndex: Int = 0, ignoreCase: Boole
|
||||
*/
|
||||
public fun String.lastIndexOf(char: Char, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Int {
|
||||
return if (ignoreCase)
|
||||
lastIndexOfAny(charArray(char), startIndex, ignoreCase)?.first ?: -1
|
||||
lastIndexOfAny(charArray(char), startIndex, ignoreCase)
|
||||
else
|
||||
nativeLastIndexOf(char, startIndex)
|
||||
}
|
||||
@@ -633,7 +661,7 @@ public fun String.lastIndexOf(char: Char, startIndex: Int = lastIndex, ignoreCas
|
||||
*/
|
||||
public fun String.lastIndexOf(string: String, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Int {
|
||||
return if (ignoreCase)
|
||||
lastIndexOfAny(listOf(string), startIndex, ignoreCase)?.first ?: -1
|
||||
lastIndexOfAny(listOf(string), startIndex, ignoreCase)
|
||||
else
|
||||
nativeLastIndexOf(string, startIndex)
|
||||
}
|
||||
@@ -717,7 +745,7 @@ private class DelimitedRangesSequence(private val string: String, private val st
|
||||
private fun String.rangesDelimitedBy(vararg delimiters: Char, startIndex: Int = 0, ignoreCase: Boolean = false, limit: Int = 0): Sequence<IntRange> {
|
||||
require(limit >= 0, { "Limit must be non-negative, but was $limit" })
|
||||
|
||||
return DelimitedRangesSequence(this, startIndex, limit, { startIndex -> indexOfAny(delimiters, startIndex, ignoreCase = ignoreCase)?.let { Pair(it.first, 1) }})
|
||||
return DelimitedRangesSequence(this, startIndex, limit, { startIndex -> findAnyOf(delimiters, startIndex, ignoreCase = ignoreCase, last = false)?.let { it.first to 1 } })
|
||||
}
|
||||
|
||||
|
||||
@@ -739,7 +767,7 @@ private fun String.rangesDelimitedBy(vararg delimiters: String, startIndex: Int
|
||||
require(limit >= 0, { "Limit must be non-negative, but was $limit" } )
|
||||
val delimitersList = delimiters.asList()
|
||||
|
||||
return DelimitedRangesSequence(this, startIndex, limit, { startIndex -> indexOfAny(delimitersList, startIndex, ignoreCase = ignoreCase)?.let { Pair(it.first, it.second.length() )} })
|
||||
return DelimitedRangesSequence(this, startIndex, limit, { startIndex -> findAnyOf(delimitersList, startIndex, ignoreCase = ignoreCase, last = false)?.let { it.first to it.second.length ()} })
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -315,57 +315,87 @@ class StringTest {
|
||||
test fun indexOfAnyChar() {
|
||||
val string = "abracadabra"
|
||||
val chars = charArray('d','b')
|
||||
assertEquals(1 to 'b', string.indexOfAny(chars))
|
||||
assertEquals(6 to 'd', string.indexOfAny(chars, startIndex = 2))
|
||||
assertEquals(null, string.indexOfAny(chars, startIndex = 9))
|
||||
assertEquals(1, string.indexOfAny(chars))
|
||||
assertEquals(6, string.indexOfAny(chars, startIndex = 2))
|
||||
assertEquals(-1, string.indexOfAny(chars, startIndex = 9))
|
||||
|
||||
assertEquals(8 to 'b', string.lastIndexOfAny(chars))
|
||||
assertEquals(6 to 'd', string.lastIndexOfAny(chars, startIndex = 7))
|
||||
assertEquals(null, string.lastIndexOfAny(chars, startIndex = 0))
|
||||
assertEquals(8, string.lastIndexOfAny(chars))
|
||||
assertEquals(6, string.lastIndexOfAny(chars, startIndex = 7))
|
||||
assertEquals(-1, string.lastIndexOfAny(chars, startIndex = 0))
|
||||
|
||||
assertEquals(null, string.indexOfAny(charArray()))
|
||||
assertEquals(-1, string.indexOfAny(charArray()))
|
||||
}
|
||||
|
||||
test fun indexOfAnyCharIgnoreCase() {
|
||||
val string = "abraCadabra"
|
||||
val chars = charArray('B','c')
|
||||
assertEquals(1 to 'B', string.indexOfAny(chars, ignoreCase = true))
|
||||
assertEquals(4 to 'c', string.indexOfAny(chars, startIndex = 2, ignoreCase = true))
|
||||
assertEquals(null, string.indexOfAny(chars, startIndex = 9, ignoreCase = true))
|
||||
assertEquals(1, string.indexOfAny(chars, ignoreCase = true))
|
||||
assertEquals(4, string.indexOfAny(chars, startIndex = 2, ignoreCase = true))
|
||||
assertEquals(-1, string.indexOfAny(chars, startIndex = 9, ignoreCase = true))
|
||||
|
||||
assertEquals(8 to 'B', string.lastIndexOfAny(chars, ignoreCase = true))
|
||||
assertEquals(4 to 'c', string.lastIndexOfAny(chars, startIndex = 7, ignoreCase = true))
|
||||
assertEquals(null, string.lastIndexOfAny(chars, startIndex = 0, ignoreCase = true))
|
||||
assertEquals(8, string.lastIndexOfAny(chars, ignoreCase = true))
|
||||
assertEquals(4, string.lastIndexOfAny(chars, startIndex = 7, ignoreCase = true))
|
||||
assertEquals(-1, string.lastIndexOfAny(chars, startIndex = 0, ignoreCase = true))
|
||||
}
|
||||
|
||||
test fun indexOfAnyString() {
|
||||
val string = "abracadabra"
|
||||
val substrings = listOf("rac", "ra")
|
||||
assertEquals(2 to "rac", string.indexOfAny(substrings))
|
||||
assertEquals(9 to "ra", string.indexOfAny(substrings, startIndex = 3))
|
||||
assertEquals(2 to "ra", string.indexOfAny(substrings.reverse()))
|
||||
assertEquals(null, string.indexOfAny(substrings, 10))
|
||||
assertEquals(2, string.indexOfAny(substrings))
|
||||
assertEquals(9, string.indexOfAny(substrings, startIndex = 3))
|
||||
assertEquals(2, string.indexOfAny(substrings.reverse()))
|
||||
assertEquals(-1, string.indexOfAny(substrings, 10))
|
||||
|
||||
assertEquals(9 to "ra", string.lastIndexOfAny(substrings))
|
||||
assertEquals(2 to "rac", string.lastIndexOfAny(substrings, startIndex = 8))
|
||||
assertEquals(2 to "ra", string.lastIndexOfAny(substrings.reverse(), startIndex = 8))
|
||||
assertEquals(null, string.lastIndexOfAny(substrings, 1))
|
||||
assertEquals(9, string.lastIndexOfAny(substrings))
|
||||
assertEquals(2, string.lastIndexOfAny(substrings, startIndex = 8))
|
||||
assertEquals(2, string.lastIndexOfAny(substrings.reverse(), startIndex = 8))
|
||||
assertEquals(-1, string.lastIndexOfAny(substrings, 1))
|
||||
|
||||
assertEquals(0 to "", string.indexOfAny(listOf("dab", "")), "empty strings are not ignored")
|
||||
assertEquals(null, string.indexOfAny(listOf()))
|
||||
assertEquals(0, string.indexOfAny(listOf("dab", "")), "empty strings are not ignored")
|
||||
assertEquals(-1, string.indexOfAny(listOf()))
|
||||
}
|
||||
|
||||
test fun indexOfAnyStringIgnoreCase() {
|
||||
val string = "aBraCadaBrA"
|
||||
val substrings = listOf("rAc", "Ra")
|
||||
|
||||
assertEquals(2 to substrings[0], string.indexOfAny(substrings, ignoreCase = true))
|
||||
assertEquals(9 to substrings[1], string.indexOfAny(substrings, startIndex = 3, ignoreCase = true))
|
||||
assertEquals(null, string.indexOfAny(substrings, startIndex = 10, ignoreCase = true))
|
||||
assertEquals(2, string.indexOfAny(substrings, ignoreCase = true))
|
||||
assertEquals(9, string.indexOfAny(substrings, startIndex = 3, ignoreCase = true))
|
||||
assertEquals(-1, string.indexOfAny(substrings, startIndex = 10, ignoreCase = true))
|
||||
|
||||
assertEquals(9 to substrings[1], string.lastIndexOfAny(substrings, ignoreCase = true))
|
||||
assertEquals(2 to substrings[0], string.lastIndexOfAny(substrings, startIndex = 8, ignoreCase = true))
|
||||
assertEquals(null, string.lastIndexOfAny(substrings, startIndex = 1, ignoreCase = true))
|
||||
assertEquals(9, string.lastIndexOfAny(substrings, ignoreCase = true))
|
||||
assertEquals(2, string.lastIndexOfAny(substrings, startIndex = 8, ignoreCase = true))
|
||||
assertEquals(-1, string.lastIndexOfAny(substrings, startIndex = 1, ignoreCase = true))
|
||||
}
|
||||
|
||||
test fun findAnyOfStrings() {
|
||||
val string = "abracadabra"
|
||||
val substrings = listOf("rac", "ra")
|
||||
assertEquals(2 to "rac", string.findAnyOf(substrings))
|
||||
assertEquals(9 to "ra", string.findAnyOf(substrings, startIndex = 3))
|
||||
assertEquals(2 to "ra", string.findAnyOf(substrings.reverse()))
|
||||
assertEquals(null, string.findAnyOf(substrings, 10))
|
||||
|
||||
assertEquals(9 to "ra", string.findLastAnyOf(substrings))
|
||||
assertEquals(2 to "rac", string.findLastAnyOf(substrings, startIndex = 8))
|
||||
assertEquals(2 to "ra", string.findLastAnyOf(substrings.reverse(), startIndex = 8))
|
||||
assertEquals(null, string.findLastAnyOf(substrings, 1))
|
||||
|
||||
assertEquals(0 to "", string.findAnyOf(listOf("dab", "")), "empty strings are not ignored")
|
||||
assertEquals(null, string.findAnyOf(listOf()))
|
||||
}
|
||||
|
||||
test fun findAnyOfStringsIgnoreCase() {
|
||||
val string = "aBraCadaBrA"
|
||||
val substrings = listOf("rAc", "Ra")
|
||||
|
||||
assertEquals(2 to substrings[0], string.findAnyOf(substrings, ignoreCase = true))
|
||||
assertEquals(9 to substrings[1], string.findAnyOf(substrings, startIndex = 3, ignoreCase = true))
|
||||
assertEquals(null, string.findAnyOf(substrings, startIndex = 10, ignoreCase = true))
|
||||
|
||||
assertEquals(9 to substrings[1], string.findLastAnyOf(substrings, ignoreCase = true))
|
||||
assertEquals(2 to substrings[0], string.findLastAnyOf(substrings, startIndex = 8, ignoreCase = true))
|
||||
assertEquals(null, string.findLastAnyOf(substrings, startIndex = 1, ignoreCase = true))
|
||||
}
|
||||
|
||||
test fun indexOfChar() {
|
||||
@@ -378,8 +408,8 @@ class StringTest {
|
||||
assertEquals(2, string.lastIndexOf('e', 3))
|
||||
|
||||
for (startIndex in -1..string.length()+1) {
|
||||
assertEquals(string.indexOfAny(charArray('e'), startIndex)?.first ?: -1, string.indexOf('e', startIndex))
|
||||
assertEquals(string.lastIndexOfAny(charArray('e'), startIndex)?.first ?: -1, string.lastIndexOf('e', startIndex))
|
||||
assertEquals(string.indexOfAny(charArray('e'), startIndex), string.indexOf('e', startIndex))
|
||||
assertEquals(string.lastIndexOfAny(charArray('e'), startIndex), string.lastIndexOf('e', startIndex))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -395,8 +425,8 @@ class StringTest {
|
||||
|
||||
|
||||
for (startIndex in -1..string.length()+1){
|
||||
assertEquals(string.indexOfAny(charArray('e'), startIndex, ignoreCase = true)?.first ?: -1, string.indexOf('E', startIndex, ignoreCase = true))
|
||||
assertEquals(string.lastIndexOfAny(charArray('E'), startIndex, ignoreCase = true)?.first ?: -1, string.lastIndexOf('e', startIndex, ignoreCase = true))
|
||||
assertEquals(string.indexOfAny(charArray('e'), startIndex, ignoreCase = true), string.indexOf('E', startIndex, ignoreCase = true))
|
||||
assertEquals(string.lastIndexOfAny(charArray('E'), startIndex, ignoreCase = true), string.lastIndexOf('e', startIndex, ignoreCase = true))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user