4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

joinToStringがとても便利だったので今更紹介する

Last updated at Posted at 2020-06-23

概要

今回は単発&短めです

SQLのqueryやAPIリクエスト時のURLパラメータなど、とあるデータから配列からカンマ区切りで要素をStringにしたものを使ったり、そこにprefixをつけたりだとかするときに皆さんはどうするでしょうか
(自分はyoutubeAPIにカンマ区切りで複数のパラメータを渡す際にどうしようかと思っていました)

StringBuilderを作ってappendしたり、配列をそのまま文字列に変換してreplaceしたり色々やり方はありそうですね

ただ今回は、標準実装されているjoinToStringがとても便利だなと思ったので今更ですが紹介&解説させていただきたいと思います

解説

元コードはこちらです

_Collections.kt
/**
 * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied.
 * 
 * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit]
 * elements will be appended, followed by the [truncated] string (which defaults to "...").
 * 
 * @sample samples.collections.Collections.Transformations.joinToString
 */
public fun <T> Iterable<T>.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String {
    return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString()
}

collection, sequenceに対して使うことができます
※上記のコードはIterableのものです

引数がかなり豊富で取り回しがききます

  • separator -> 要素をそのままつなげるわけではなく、それぞれにseparatorを指定できます

    • | でも - でも , でも。空白であればそのままです
  • prefix -> 文字通り連結したものの先頭に加えたいものを指定できます

  • postfix -> 最後に加えたいものを指定できます

  • limit -> 連結する際、何個の要素まで使うか指定できます

    • defaultは-1つまりlimitをかけないということですが、これが2だった場合は連結する要素は2つまでということになります
  • truncated -> limitと合わせて使うものになります。limitによって配列の要素が全て使われず省略されてしまう場合に、ここで指定した文字列を追加することができます

    • 例えば ... としておくと文字列の最後に...が付与されて省略された形を表現できます
    • ただし、上述したpostfixが設定されている場合はそれが最後にくることに注意してください
  • transform -> 関数から値の変換ができます mapのようなものですね

実装

試しにかんたんな例を実装してみます

fun main() {
    val records = listOf(Record("Hoge", "Huga", 20000),
                         Record("A", "B", 2500),
                         Record("B", "C", 1200)
                         )
    val result = records.joinToString(limit=2, truncated="...", prefix="---*** ", postfix=" ***---", separator = ", ", transform = {
            record -> "${record.from} -> ${record.to} (${record.price})"
        })
    println(result)
}

data class Record(val from: String, val to: String, val price: Int)

誰が誰あてにどれほどのお金を振り込んだかを表すレコードとでも思ってください
実際にこのような形で実行すると

---*** Hoge -> Huga (20000), A -> B (2500), ... ***---

とてもきれいな出力が得られました 便利です

競技プログラミングでも使えそうですね

上記コードはこちらのKotlin Playgroundでお試しできます

ref

4
4
2

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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?