1. 序章

リストはKotlinの基本的なコレクションの1つであり、要素のコレクションをプレーンな文字列に変換することは、かなり一般的なユースケースです。 このチュートリアルでは、リスト文字列に簡単に変換する方法を学習します。

2. joinToString を使用して、ListStringに変換する

Kotlin Collections APIには、コレクションに対して操作を実行するための多くの便利なメソッドがあります。 それらの1つはjoinToStringです。 このメソッドは、コレクション内のすべての要素から文字列を作成します。デフォルトの区切り文字はコンマです。

リストを定義して、joinToStringの出力を確認しましょう。

val numbers = listOf(11, 22, 3, 41, 52, 6)
val string = numbers.joinToString()
assertEquals("11, 22, 3, 41, 52, 6", string)

セパレータ、プレフィックス、サフィックスのパラメータを定義して、出力文字列をカスタマイズできます。

val numbers = listOf(11, 22, 3, 41, 52, 6)
val string = numbers.joinToString(prefix = "<", postfix = ">", separator = "")
assertEquals("<1122341526>", string)

リストが長すぎる場合は制限を設定することもできます。また、変換ラムダを設定することもできます。

val chars = charArrayOf('h', 'e', 'l', 'l', 'o', 'o', 'o', 'o')
val string = chars.joinToString(separator = "", limit = 5, truncated = "!") { it.uppercaseChar().toString() }
assertEquals("HELLO!", string)

3. joinTo を使用して、既存のテキストにListを追加する

すでに文字列またはテキストがあり、リストの要素をリストに追加したい場合は、joinToメソッドを使用できます。 StringBuilderを使用して、すべてのリスト要素から形成された文字列を既存の文字列に追加します。前の例のように、パラメーターを指定すると、出力文字列をカスタマイズできます。

val sb = StringBuilder("An existing string and a list: ")
val numbers = listOf(11, 22, 3, 41, 52, 6)
val string = numbers.joinTo(sb).toString()
assertEquals("An existing string and a list: 11, 22, 3, 41, 52, 6", string)

実際のところ、 joinTo は、Appendableインターフェイスを実装するクラスをbuffer引数として受け取ります。 ただし、標準ライブラリではStringBuilderのみがこれを実行します。 このメソッドは、 buffer 引数と同じ型を返すため、StringBuilder。である可能性があります。

4. reducefoldを使用して、フィードバックを使用してListからStringを作成します。

使用することもできます減らすリストから文字列を形成する関数。 削減機能は、最初の要素から値を累積します。 次に、左から右への操作を現在のアキュムレータ値と後続の各要素に適用します。 したがって、アキュムレータの次の各値は、それがすでに保持している値に依存する可能性があります。

val strings = listOf("a", "b", "a", "c", "c", "d", "b", "a")
val uniqueSubstrings = strings.reduce { acc, string -> if (string !in acc) acc + string else acc }
assertEquals("abcd", uniqueSubstrings)

記述されているように、このコードは各反復で新しいStringインスタンスをインスタンス化します。 これは、大規模なコレクションでは、このようなアプローチがアプリケーションのパフォーマンスに非常に悪影響を与える可能性があることを意味します。

次に、空のコレクションを減らすことはできません。 代わりに、例外をスローします。 したがって、reduceを使用するコードの部分を注意深く監視する必要があります。

同じタスクへの別のアプローチは、fold関数である可能性があります。 joinTojoinToStringと同じように、 reduce です。最初の反復でアキュムレータとして使用される初期値を指定する必要があります:

val strings = listOf("a", "b", "a", "c", "c", "d", "b", "a")
val uniqueSubstrings =
    strings.fold(StringBuilder()) { acc, string -> if (string !in acc) acc.append(string) else acc }
assertEquals("abcd", uniqueSubstrings.toString())

このようにして、コレクションに対して StringBuilder を使用できるため、reduceのメモリとパフォーマンスの問題を回避できます。

5. ループ

最後に、単純な連結を使用して、文字ごとに文字列を作成できます。 これを行うには、リストをループして、各文字を一度に1つずつ文字列に連結します。 例を見てみましょう:

val elements = listOf("a", "b", "c", "d", "e")
var string = ""

for(s in elements){
    string += s
}

assertEquals("abcde", string)

このアプローチは、 reduce で見たものと同様に、大規模なコレクションが含まれる場合の危険性です。 代わりに、StringBuilderを使用して同じことを行うことができます。

val letters = listOf("a", "b", "c", "d", "e", "f")
val builder = StringBuilder()

for(s in letters){
    builder.append(s)
}

assertEquals("abcdef", builder.toString())

実際、 Kotlinには、StringBuilderの処理をはるかに快適にするための優れたシンタックスシュガーがあります

val letters = listOf("a", "b", "c", "d", "e", "f")
val alreadyAString = buildString { for (s in letters) append(s) } // `this` is a StringBuilder inside the lambda
assertEquals("abcdef", alreadyAString)

出力をカスタマイズするには、StringBuilderStringとして返した後、 removeSuffix()のような組み込み関数を使用できます。

val letters = listOf("a", "b", "c", "d", "e", "f")
val string = buildString { letters.forEach(::append) }
val withoutSuffix = string.removeSuffix("f")
assertEquals("abcde", withoutSuffix)

6. 結論

この記事では、Kotlinでリストを文字列に変換する最も一般的な方法を見てきました。 Kotlinの組み込み関数を使用すると、コードがよりクリーンになり、言語の規則に従うことができます。 出力文字列を簡単にカスタマイズすることもできます。 いつものように、すべての例はGitHubから入手できます。