1. 概要

このチュートリアルでは、要素のコレクション、特にStringのコレクションから単一のStringを作成する方法を説明します。

2. 文字列のコレクションに参加する

開発者として、私たちはしばしば要素のコレクションを扱う必要があります。 リストアレイ、 セットのいずれであっても、現時点では重要ではありません。 多くの場合、これらすべての要素を1つのStringに結合する必要があります。 たとえば、段落のリストが表示され、すべての段落を全文として結合したいとしますさらに、改行文字を使用してすべての段落を結合したいとします。 ( \ n )。

各プログラミング言語には、これを実現する独自の方法があります。 標準のlibユーティリティ関数で問題を解決するものもあります。 他の人は外部ライブラリを使用します。 そして、他のいくつかは、要素をループするなどの素朴なソリューションを使用してそれを解決します。

この問題を解決するためのさまざまなアプローチを見てみましょう。

2.1. mkStringを使用する

最初の解決策はおそらく最も慣用的であり、使用は非常に簡単です。 mkStringメソッドを呼び出すことができ、コレクション要素を連結します

scala> List("a","b","c").mkString 
val res1: String = abc

素晴らしいボーナスとして、を使用すると、コレクションの各Stringの間にカスタムセパレーターを指定することもできます。

scala> List("a","b","c").mkString(",") 
val res2: String = a,b,c 

scala> List("a","b","c").mkString("-") 
val res3: String = a-b-c

このソリューションは、すべての GenTraversableOnceで機能します。これは、List、Set、Arrayなどの最も一般的な標準コレクションで使用できることを意味します。

scala> Array("a","b","c").mkString("/")
val res4: String = a/b/c

scala> Set("a","b","c").mkString("/")
val res5: String = a/b/c

scala> Map("a"->"A","b"->"B").mkString(" // ")
val res6: String = a -> A // b -> B

2.2. フォールドメソッドの使用

Scala標準ライブラリは、コレクションを反復処理するための多くのメソッドを提供します。 最も強力なものの1つは ‘fold family’メソッド:foldLeftおよび foldRight。 それらの違いについては説明しませんが、最小限の変更でこれらのいずれかを例で使用できるはずです。 読者の挑戦として残しておきます。

これらのメソッドは2つの引数を受け取ります。 1つ目は、空の状態を表す初期値です。 2番目の引数はマージ関数です。 関数は、現在の累積値を次の反復要素とマージします。

scala> List("a","b","c").fold("") { (accumulator, elem) => accumulator + "" + elem }
val res0: String = abc

このソリューションは読みにくいかもしれませんが、マージ関数で高価な操作を実行できるため、より強力です。 一方、 mkString 関数のように、エッジケースをうまく処理することはできません。 たとえば、単純な関数を使用すると、連結されたStringの先頭に不要なセパレータが追加されます。

scala> List("a","b","c").fold("") { (accumulator, elem) => accumulator + "/" + elem }
val res1: String = /a/b/c

解決策は、アキュムレータ変数が空かどうかをチェックするためのより複雑なロジックを追加することです。 または、単に最初の文字をドロップすることもできます。

2.3. Reduceメソッドの使用

fold ファミリーメソッドに非常によく似た別の方法、reduceファミリーメソッドを使用することもできます。 対応するものと同じように、微妙な違いがあるいくつかのメソッドがあります。 。 foldメソッドとは異なり、空でないコレクションを想定しているため、初期の空の状態のパラメーターはありません。

scala> List("a","b","c").reduce { (accumulator, elem) => accumulator + elem }
val res0: String = abc

scala> List("a","b","c").reduce { (accumulator, elem) => accumulator + "/" + elem }
val res1: String = a/b/c

2.4. String連結の使用

最後に、最も単純なソリューションである単純なループを使用します。

scala> var result = ""
var result: String = ""

scala> for (elem <- List("a","b","c")) {
     | result = result + "/" + elem
     | }

scala> result
val res0: String = /a/b/c

これはScalaの慣用的なコードとはほど遠いことを考慮に入れてください。これは、最後の手段としてのみ使用する必要があります。

2.5. カスタムオブジェクトの結合

これまで、Stringを単一のStringに結合してきました。 しかし、オブジェクトのリストがあり、それらのすべての属性を1つのStringに結合したいとします。 たとえば、CSVファイルとしてエクスポートする必要がある場合があります。これは、コンマで区切られた値のStringにすぎません。

これを実現する最も簡単な方法は、カスタムオブジェクトをその文字列表現に変換することから始めることです。 その後、前のセクションでこれまでに学んだことを適用できます。 たとえば、ケースクラスを使用している場合、それは簡単です。

scala> case class Person(firstName: String, lastName: String)
class Person

scala> val p1 = Person("John", "Doe")
val p1: Person = Person(John,Doe)

scala> val p2 = Person("Jane", "Doe")
val p2: Person = Person(Jane,Doe)

scala> List(p1,p2).map(_.toString).mkString(" and ")
val res0: String = Person(John,Doe) and Person(Jane,Doe)

3. 結論

この記事では、Scalaを使用してStringのコレクションを1つに結合するためのさまざまなソリューションを見てきました。