Align JS String.equals/compareTo(ignoreCase) behavior with JVM #KT-48999

This commit is contained in:
Abduqodiri Qurbonzoda
2021-09-30 15:35:50 +00:00
committed by Space
parent b5f74ef9a6
commit f8bcba0b76
8 changed files with 77 additions and 30 deletions
+19 -15
View File
@@ -244,6 +244,11 @@ public inline fun String.match(regex: String): Array<String>? = asDynamic().matc
@kotlin.internal.InlineOnly
internal inline fun String.nativeReplace(pattern: RegExp, replacement: String): String = asDynamic().replace(pattern, replacement)
/**
* Compares two strings lexicographically, optionally ignoring case differences.
*
* If [ignoreCase] is true, the result of `Char.uppercaseChar().lowercaseChar()` on each character is compared.
*/
@SinceKotlin("1.2")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun String.compareTo(other: String, ignoreCase: Boolean = false): Int {
@@ -252,24 +257,23 @@ public actual fun String.compareTo(other: String, ignoreCase: Boolean = false):
val n2 = other.length
val min = minOf(n1, n2)
if (min == 0) return n1 - n2
var start = 0
while (true) {
val end = minOf(start + 16, min)
var s1 = this.substring(start, end)
var s2 = other.substring(start, end)
if (s1 != s2) {
s1 = s1.uppercase()
s2 = s2.uppercase()
if (s1 != s2) {
s1 = s1.lowercase()
s2 = s2.lowercase()
if (s1 != s2) {
return s1.compareTo(s2)
for (index in 0 until min) {
var thisChar = this[index]
var otherChar = other[index]
if (thisChar != otherChar) {
thisChar = thisChar.uppercaseChar()
otherChar = otherChar.uppercaseChar()
if (thisChar != otherChar) {
thisChar = thisChar.lowercaseChar()
otherChar = otherChar.lowercaseChar()
if (thisChar != otherChar) {
return thisChar.compareTo(otherChar)
}
}
}
if (end == min) break
start = end
}
return n1 - n2
} else {
@@ -61,19 +61,33 @@ public fun String.matches(regex: String): Boolean {
*/
public actual fun CharSequence.isBlank(): Boolean = length == 0 || indices.all { this[it].isWhitespace() }
/**
* Returns `true` if this string is equal to [other], optionally ignoring character case.
*
* Two strings are considered to be equal if they have the same length and the same character at the same index.
* If [ignoreCase] is true, the result of `Char.uppercaseChar().lowercaseChar()` on each character is compared.
*
* @param ignoreCase `true` to ignore character case when comparing strings. By default `false`.
*/
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean =
when {
this == null -> other == null
!ignoreCase -> this == other
other == null -> false
else -> {
val thisLower = this.lowercase()
val otherLower = other.lowercase()
thisLower == otherLower || (thisLower.uppercase() == otherLower.uppercase())
public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean {
if (this == null) return other == null
if (other == null) return false
if (!ignoreCase) return this == other
if (this.length != other.length) return false
for (index in 0 until this.length) {
val thisChar = this[index]
val otherChar = other[index]
if (!thisChar.equals(otherChar, ignoreCase)) {
return false
}
}
return true
}
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun CharSequence.regionMatches(thisOffset: Int, other: CharSequence, otherOffset: Int, length: Int, ignoreCase: Boolean = false): Boolean =