LoginSignup
0
1

More than 3 years have passed since last update.

kotlin.text から5選

Posted at

前書き

この記事を投稿するまでにだいぶ時間が空いてしまいましたが、Kotlin Fest 2019 に参加してきました。
いくつか講演を聞く中で、Kotlin について慣れるまではなかなか Kotlin らしい書き方をするのは難しいかもしれないが、kotlin.text パッケージの機能を使ってみたりすると良いのではないかというのがありました(要約にして意訳)

そこでほぼ公式からの写経になってしまいますが、いくつか試して理解を進めたものを残しておきます。
コードはAndroid StudioのREPL(Kotlin version 1.3.31)で確認しております。

all

inline fun CharSequence.all(
    predicate: (Char) -> Boolean
): Boolean

すべての文字が指定されたpredicateと一致するかどうかを返します。

sample
// CharRange型に abc を格納します
val range_a_c = 'a'..'c'
// 引数で渡された文字が range_a_c に含まれていたら true を返す predicate
val isInRange: (Char) -> Boolean = { it in range_a_c }

val alphabet_a_g = "abcdefg"
println("alphabet_a_g.all { isInRange(it) } is ${alphabet_a_g.all { isInRange(it) }}") // false

val alphabet_a_c = "abc"
println("alphabet_a_c.all { isInRange(it) } is ${alphabet_a_c.all { isInRange(it) }}") // true

isLetter

いきなりなんか普通っぽいセレクトになりましたが次で使うため(笑)

fun Char.isLetter(): Boolean

文字であるかどうかを返却します。

sample
val chars = listOf('a', 'あ', '&', '9')
// partition を用いて、isLetter() により、文字とそうでないものを分ける
val (letters, notLetters) = chars.partition { it.isLetter() }
println(letters) // [a, あ]
println(notLetters) // [&, 9]

takeなんちゃら4種

fun CharSequence.take(n: Int): CharSequence

文字列の先頭からn文字を返却します。
nより文字列が短い場合は文字列全体を返却します。

fun CharSequence.takeLast(n: Int): CharSequence

文字列の最後からn文字を返却します。
nより文字列が短い場合は文字列全体を返却します。

inline fun CharSequence.takeWhile(
    predicate: (Char) -> Boolean
): CharSequence

文字列から指定された predicate を満たす最初の文字列を返却します。

inline fun CharSequence.takeLastWhile(
    predicate: (Char) -> Boolean
): CharSequence

文字列から指定された predicate を満たす最後の文字列を返却します。

sample
val string = "+++ *** TAKE &&& SAMPLE >>>"
println(string.take(12)) //+++ *** TAKE
println(string.takeLast(10)) //SAMPLE >>>
println(string.takeWhile { !it.isLetter() }) //+++ *** 
println(string.takeLastWhile { !it.isLetter() }) // >>>

zip

指定された変換関数 (transform) を文字の各ペアに適用して、このインデックスと同じインデックスを持つ他の文字列 (other) から構築された値のリストを返します。返されるリストは、最短の文字列の長さとなります。

inline fun <V> CharSequence.zip(
    other: CharSequence,
    transform: (a: Char, b: Char) -> V
): List<V>
sample
val stringA = "abcd"
val stringB = "zyx"
// {} 内が transform にあたるラムダ式
val result = stringA.zip(stringB) { a, b -> "$a$b" }
// stringBのほうが短いため、stringBの長さの配列が返却される
println(result) // [az, by, cx]

chunked

fun <R> CharSequence.chunked(
    size: Int,
    transform: (CharSequence) -> R
): List<R>

文字列を、指定されたサイズを超えない複数の文字列に分割し、指定された transform をそれぞれに適用した結果の配列を返却します。

sample
val table = mapOf("MLB" to "Baseball", "NFL" to "Football", "NBA" to "Basketball", "NHL" to "Hockey", "QB" to "quarterback")
val concatenated = "MLBNHLNFLMLSNBAQB"

// concatenated を 3文字ずつに分けて、transform を適用する
// 最後は3文字に満たない範囲で分割する
// table に無い場合は、"Unknown" とする
val results = concatenated.chunked(3) { 
abbreviation: CharSequence -> table[abbreviation.toString()] ?: "Unknown" }

println(results) // [Baseball, Hockey, Football, Unknown, Basketball, quarterback]

後書き

正直な話、Qiita投稿練習用の記事ではありましたが、Kotlinの基礎的なところを見直す機会となりました。
「それでも少しは目新しいものを」とか欲を出したせいで、
普通にアプリを作る上では、使いどころに困るものも選んでしまった感があります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1