■ はじめに
https://dk521123.hatenablog.com/entry/2023/03/12/184331
の続き。 Scala で デフォルトでは、break文がないと知ったので ループに関して調べてみた
目次
【1】ループ 1)while文 2)for文 3)foreach文 【2】便利なメソッド 1)map 2)foldLeft / foldRight 3)zipWithIndex 【3】使用上の注意 【4】トラブル 1)エラー「value foreach is not a member of java.util.List[XXXX]」発生時
【1】ループ
* 注目すべき Java との違いは、for文の構文が変わった
1)while文
* Java と変わらない
2)for文
for(i <- 1 to 3){ println(i) } var array = Array(1, 2, 3) for (x <- array) { println(x) }
注意点:Javaとの違い
// () -> {} でもOK object Hello { def main(args: Array[String]): Unit = { // for { i <- 1 to 3 } for { i <- 1 to 3 } println(s"i = ${i}") } }
for yield
* 以下の関連記事を参照のこと
https://dk521123.hatenablog.com/entry/2023/09/06/232921
3)foreach文
(1 to 3).foreach( i => println(i)) var array = Array(1, 2, 3) (array).foreach( x => println(x))
【2】便利なメソッド
1)map
* 各要素に対して処理を行い、その結果を返すメソッド
ループ処理をする方法は?mapメソッドの使い方|Scalapedia
用途
* 各要素を変換するために使用
サンプル
object Hello { def main(args: Array[String]): Unit = { val array = Array(1, 2, 3, 4, 5) val results = array.map(x => x * 2) results.foreach(value => println(s"result = ${value}")) } }
出力結果
result = 2 result = 4 result = 6 result = 8 result = 10
2)foldLeft / foldRight
* 畳み込む機能(例えば、階乗) + foldLeft : 左から右に走査する + foldRight : 右から左に走査する
https://dev.classmethod.jp/articles/scala-foldright-foldleft/
https://zenn.dev/smzst/articles/e7150c88c0d927
構文
// def foldLeft[B](z: B)(op: (B, A) => B): B // [B]: 戻り値のデータ型 // z: 初期値 (0: Int) // op の第一引数が accumulator (sum)、第二引数が各値 (x ... 1,2,3) Seq(1, 2, 3).foldLeft[Int](0: Int)((sum, x) => x + sum) // 6
サンプル
object Hello { def main(args: Array[String]): Unit = { val array = Array(1, 2, 3, 4, 5) // 階乗 val result1 = array.foldLeft(1) { (accumulation, value) => accumulation * value } // 120 println(result1) println(array.product) // 合計 val result2 = array.foldLeft(0) { (sum, value) => sum + value } // 15 println(result2) println(array.sum) } }
3)zipWithIndex
* インデックス付きのループ
https://qiita.com/takilog/items/f1dfa544580f1a3a6264
サンプル
import java.util.Date import scala.util.Try object Hello { def main(args: Array[String]): Unit = { val targets = Array("2013-07-06", "20130706", "2013.07.06") targets.zipWithIndex.foreach { case(target:String, index:Int) => { val result = getDate(target) // [0] Sat Jul 06 00:00:00 JST 2013 // [1] Sat Jul 06 00:00:00 JST 2013 // [2] None println(s"[${index}] ${result.getOrElse("None")}") } } } private def getDate(target: String): Option[Date] = { val dateFormats = Array("yyyy/MM/dd", "yyyy-MM-dd", "yyyyMMdd") dateFormats.foldLeft[Option[Date]](None) { (parsed, dateFormat) => val format = new java.text.SimpleDateFormat(dateFormat) parsed.orElse(Try(format.parse(target)).toOption) } } }
【3】使用上の注意
* 冒頭でも書いたが...
[1] break文がデフォルトではない
* ただし、対応案あり。
[2] continue文もない
* 完全にない(実装で工夫するしかない) break / continue については、以下の関連記事で深堀りする
Scala ~ break / continue ~
https://dk521123.hatenablog.com/entry/2023/10/14/011736
[3] Javaコードのコレクションのループは「import scala.collection.JavaConversions._」が必要
* 詳細は、後述「【4】トラブル」の「1)エラー「・・・」を参照
【4】トラブル
1)エラー「value foreach is not a member of java.util.List[XXXX]」発生時
を参考に Scala コードで書き直していたら、 以下「エラー発生コード」の★の場所で 以下「エラー内容」が表示された
エラー発生コード
// See https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html val listObjResponse = s3Client.listObjectsV2(listObjectsReqManual) // See https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Object.html for (content <- listObjResponse.contents()) { // ★ここでエラー★
エラー内容
value foreach is not a member of java.util.List[software.amazon.awssdk.services.s3.model.S3Object]
対応案
コードの冒頭に import scala.collection.JavaConversions._ を付与する
https://github.com/sryza/aas/issues/20
関連記事
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / Option型 ~
https://dk521123.hatenablog.com/entry/2023/03/09/000000
Scala ~ 基本編 / メソッド ~
https://dk521123.hatenablog.com/entry/2023/03/03/000000
Scala ~ 基本編 / クラス ~
https://dk521123.hatenablog.com/entry/2023/03/14/000857
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ 基本編 / 日付・日時 ~
https://dk521123.hatenablog.com/entry/2023/03/08/000000
Scala ~ 基本編 / 正規表現 ~
https://dk521123.hatenablog.com/entry/2023/03/18/034704
Scala ~ 基本編 / ジェネリック
https://dk521123.hatenablog.com/entry/2023/03/21/003817
Scala ~ break / continue ~
https://dk521123.hatenablog.com/entry/2023/10/14/011736
Scala ~ for yield ~
https://dk521123.hatenablog.com/entry/2023/09/06/232921
Scala ~ ファイル名・パスの扱い ~
https://dk521123.hatenablog.com/entry/2023/03/11/000000
Scala ~ YAML ~
https://dk521123.hatenablog.com/entry/2023/03/16/012034
Spark/Scalaの開発環境構築 ~ Windows編 ~
https://dk521123.hatenablog.com/entry/2023/03/20/115450
SBT ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/22/000000