Reverse string in Kotlin
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
In the question of how to reverse a string in Java, a comment mentioned that combining Unicode code points need to be taken into account.
The below code works as intended for all test cases I tried. Probably there are some edge cases in other scripts and languages I do not know. I'd like to learn about these, as well as any coding style issues.
package de.roland_illig.strrev
import com.ibm.icu.lang.UCharacter
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
/**
* Returns the reversed string, keeping clusters of combining code points
* (such as German umlauts or Arabic tashkël) together.
*/
fun String.reverse(): String
fun isLamAlef(cluster: List<Int>, ch: Int) =
cluster.isNotEmpty() && cluster.first() == 0x0644 && ch == 0x0627
val clusters = mutableListOf<List<Int>>()
val cluster = mutableListOf<Int>()
this.codePoints().forEachOrdered ch ->
if (!(UCharacter.getCombiningClass(ch) != 0) && !isLamAlef(cluster, ch))
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
cluster += ch
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
return fromCodePoints(*clusters.reversed().flatten().toIntArray())
class StringReverseTest
@Test
fun ascii()
assertThat("hello".reverse()).isEqualTo("olleh")
@Test
fun surrogates()
val emoji = fromCodePoints(0x1F645)
assertThat(emoji.reverse()).isEqualTo(emoji)
@Test
fun combining()
val combinedUmlaut = fromCodePoints(0x0041, 0x0308)
assertThat(combinedUmlaut.reverse()).isEqualTo(combinedUmlaut)
@Test
fun arabic()
assertThat("ãÃÂÃÂÃÂÃÂÃÂç ÃÂàóÃÂÃÂÃÂÃÂÃÂç".reverse()).isEqualTo("ÃÂÃÂçÃÂÃÂóàÃÂàÃÂÃÂçÃÂÃÂãÃÂ")
@Test
fun combiningAtBeginning()
val combinedUmlaut = fromCodePoints(0x0308, 0x0041)
assertThat(combinedUmlaut.reverse())
.isEqualTo(fromCodePoints(0x0041, 0x0308))
private fun fromCodePoints(vararg codePoints: Int): String =
String(codePoints, 0, codePoints.size)
For completeness, here are the Gradle dependencies for build.gradle
:
dependencies
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile group: 'com.ibm.icu', name: 'icu4j', version: '61.1'
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "org.junit.jupiter:junit-jupiter-api:5.0.2"
testCompile "org.assertj:assertj-core:3.9.0"
strings kotlin unicode
add a comment |Â
up vote
3
down vote
favorite
In the question of how to reverse a string in Java, a comment mentioned that combining Unicode code points need to be taken into account.
The below code works as intended for all test cases I tried. Probably there are some edge cases in other scripts and languages I do not know. I'd like to learn about these, as well as any coding style issues.
package de.roland_illig.strrev
import com.ibm.icu.lang.UCharacter
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
/**
* Returns the reversed string, keeping clusters of combining code points
* (such as German umlauts or Arabic tashkël) together.
*/
fun String.reverse(): String
fun isLamAlef(cluster: List<Int>, ch: Int) =
cluster.isNotEmpty() && cluster.first() == 0x0644 && ch == 0x0627
val clusters = mutableListOf<List<Int>>()
val cluster = mutableListOf<Int>()
this.codePoints().forEachOrdered ch ->
if (!(UCharacter.getCombiningClass(ch) != 0) && !isLamAlef(cluster, ch))
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
cluster += ch
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
return fromCodePoints(*clusters.reversed().flatten().toIntArray())
class StringReverseTest
@Test
fun ascii()
assertThat("hello".reverse()).isEqualTo("olleh")
@Test
fun surrogates()
val emoji = fromCodePoints(0x1F645)
assertThat(emoji.reverse()).isEqualTo(emoji)
@Test
fun combining()
val combinedUmlaut = fromCodePoints(0x0041, 0x0308)
assertThat(combinedUmlaut.reverse()).isEqualTo(combinedUmlaut)
@Test
fun arabic()
assertThat("ãÃÂÃÂÃÂÃÂÃÂç ÃÂàóÃÂÃÂÃÂÃÂÃÂç".reverse()).isEqualTo("ÃÂÃÂçÃÂÃÂóàÃÂàÃÂÃÂçÃÂÃÂãÃÂ")
@Test
fun combiningAtBeginning()
val combinedUmlaut = fromCodePoints(0x0308, 0x0041)
assertThat(combinedUmlaut.reverse())
.isEqualTo(fromCodePoints(0x0041, 0x0308))
private fun fromCodePoints(vararg codePoints: Int): String =
String(codePoints, 0, codePoints.size)
For completeness, here are the Gradle dependencies for build.gradle
:
dependencies
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile group: 'com.ibm.icu', name: 'icu4j', version: '61.1'
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "org.junit.jupiter:junit-jupiter-api:5.0.2"
testCompile "org.assertj:assertj-core:3.9.0"
strings kotlin unicode
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
In the question of how to reverse a string in Java, a comment mentioned that combining Unicode code points need to be taken into account.
The below code works as intended for all test cases I tried. Probably there are some edge cases in other scripts and languages I do not know. I'd like to learn about these, as well as any coding style issues.
package de.roland_illig.strrev
import com.ibm.icu.lang.UCharacter
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
/**
* Returns the reversed string, keeping clusters of combining code points
* (such as German umlauts or Arabic tashkël) together.
*/
fun String.reverse(): String
fun isLamAlef(cluster: List<Int>, ch: Int) =
cluster.isNotEmpty() && cluster.first() == 0x0644 && ch == 0x0627
val clusters = mutableListOf<List<Int>>()
val cluster = mutableListOf<Int>()
this.codePoints().forEachOrdered ch ->
if (!(UCharacter.getCombiningClass(ch) != 0) && !isLamAlef(cluster, ch))
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
cluster += ch
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
return fromCodePoints(*clusters.reversed().flatten().toIntArray())
class StringReverseTest
@Test
fun ascii()
assertThat("hello".reverse()).isEqualTo("olleh")
@Test
fun surrogates()
val emoji = fromCodePoints(0x1F645)
assertThat(emoji.reverse()).isEqualTo(emoji)
@Test
fun combining()
val combinedUmlaut = fromCodePoints(0x0041, 0x0308)
assertThat(combinedUmlaut.reverse()).isEqualTo(combinedUmlaut)
@Test
fun arabic()
assertThat("ãÃÂÃÂÃÂÃÂÃÂç ÃÂàóÃÂÃÂÃÂÃÂÃÂç".reverse()).isEqualTo("ÃÂÃÂçÃÂÃÂóàÃÂàÃÂÃÂçÃÂÃÂãÃÂ")
@Test
fun combiningAtBeginning()
val combinedUmlaut = fromCodePoints(0x0308, 0x0041)
assertThat(combinedUmlaut.reverse())
.isEqualTo(fromCodePoints(0x0041, 0x0308))
private fun fromCodePoints(vararg codePoints: Int): String =
String(codePoints, 0, codePoints.size)
For completeness, here are the Gradle dependencies for build.gradle
:
dependencies
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile group: 'com.ibm.icu', name: 'icu4j', version: '61.1'
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "org.junit.jupiter:junit-jupiter-api:5.0.2"
testCompile "org.assertj:assertj-core:3.9.0"
strings kotlin unicode
In the question of how to reverse a string in Java, a comment mentioned that combining Unicode code points need to be taken into account.
The below code works as intended for all test cases I tried. Probably there are some edge cases in other scripts and languages I do not know. I'd like to learn about these, as well as any coding style issues.
package de.roland_illig.strrev
import com.ibm.icu.lang.UCharacter
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
/**
* Returns the reversed string, keeping clusters of combining code points
* (such as German umlauts or Arabic tashkël) together.
*/
fun String.reverse(): String
fun isLamAlef(cluster: List<Int>, ch: Int) =
cluster.isNotEmpty() && cluster.first() == 0x0644 && ch == 0x0627
val clusters = mutableListOf<List<Int>>()
val cluster = mutableListOf<Int>()
this.codePoints().forEachOrdered ch ->
if (!(UCharacter.getCombiningClass(ch) != 0) && !isLamAlef(cluster, ch))
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
cluster += ch
if (cluster.isNotEmpty())
clusters += cluster.toList()
cluster.clear()
return fromCodePoints(*clusters.reversed().flatten().toIntArray())
class StringReverseTest
@Test
fun ascii()
assertThat("hello".reverse()).isEqualTo("olleh")
@Test
fun surrogates()
val emoji = fromCodePoints(0x1F645)
assertThat(emoji.reverse()).isEqualTo(emoji)
@Test
fun combining()
val combinedUmlaut = fromCodePoints(0x0041, 0x0308)
assertThat(combinedUmlaut.reverse()).isEqualTo(combinedUmlaut)
@Test
fun arabic()
assertThat("ãÃÂÃÂÃÂÃÂÃÂç ÃÂàóÃÂÃÂÃÂÃÂÃÂç".reverse()).isEqualTo("ÃÂÃÂçÃÂÃÂóàÃÂàÃÂÃÂçÃÂÃÂãÃÂ")
@Test
fun combiningAtBeginning()
val combinedUmlaut = fromCodePoints(0x0308, 0x0041)
assertThat(combinedUmlaut.reverse())
.isEqualTo(fromCodePoints(0x0041, 0x0308))
private fun fromCodePoints(vararg codePoints: Int): String =
String(codePoints, 0, codePoints.size)
For completeness, here are the Gradle dependencies for build.gradle
:
dependencies
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile group: 'com.ibm.icu', name: 'icu4j', version: '61.1'
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "org.junit.jupiter:junit-jupiter-api:5.0.2"
testCompile "org.assertj:assertj-core:3.9.0"
strings kotlin unicode
edited Apr 29 at 18:58
asked Apr 29 at 13:50
Roland Illig
10.4k11543
10.4k11543
add a comment |Â
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193206%2freverse-string-in-kotlin%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password