Scalaアレコレ2019
Option型の変数に任意の値が入っているかどうかで処理を分岐させる
/* * 以下のようなcase classがあって、HogeがMasterHogeにOption型として格納される場合に、 * HogeのメンバフィールドであるOption型のisHoge(フラグ的なもの)の値をチェックする */ case class MasterHoge( hoge: Option[Hoge] = None ) case class Hoge( isHoge: Option[Int] = None ) // どこかでMasterHogeをインスタンス化 val masterHoge = xxxx // foreachとcontainsを使う masterHoge.foreach { hoge => if (hoge.isHoge.contains(1)) { // ココに行いたい処理を書く } }
zipWithIndex()を使ってSeqのインデックスと要素にアクセスする
val hogeSeq = Seq("a", "b", "c", "d", "e") hogeSeq.zipWithIndex.foreach{case(value, index) => { printf("${index}:${value}") // 0:a 1:b 2:c .... }}
groupBy()を使ってMapのListを1つのMapにまとめる
// ↓このようなMapのListがあったとして、これを"id"をキーとしたMapにまとめたいとする val hogeList = List( Map[String, Int]( "id" -> 1, "vid" -> 2, "value" -> 10 ), Map[String, Int]( "id" -> 2, "vid" -> 4, "value" -> 20 ), Map[String, Int]( "id" -> 1, "vid" -> 21, "value" -> 17 ), ) // "value"の降順で上記のListを並べ替えたListを作る(これは本題とは関係のない操作) val sortedList = hogeList.sortBy(_.get("value"))(Ordering[Option[Int]].reverse) val hoshiimono = sortedList.groupBy(ho => { ho.get("id").get }).map(h => { val list = h._2 h._1 -> list.map(l => { l.get("vid").get }) }) printf(s"___ ${hosiimono} ___") /* 結果 Map(2 -> List(4), 1 -> List(21, 2)) */
処理実行元のディレクトリを取得
sys.props("usr.dir")
文字列の前後にあるダブルクォーテーションを削除
以下のような形式のJSONをJSON文字列的にparseしようとしたら構文エラーとなってしまった。
"{\"hoge\":{…}…, \"hogehoge\":\"geho\"}"
最初と最後にダブルクォーテーションが入っているのが原因だったので、以下のようにして取り除いた。
// まずエスケープとして入ってしまっていたバックスラッシュを取り除く val jsonDataWithoutEscape = StringContext treatEscapes(jsonData.toString()) // 頭と後ろのダブルクォーテーションを削除 val jsonStr = jsonDataWithoutEscape.dropWhile( _ == '"' ).reverse.dropWhile( _ == '"' ).reverse
Jacksonを用いて複数階層を掘り下げつつ不要な要素を削除する
処理の流れ
- Json文字列からObjectNodeを生成
- ObjectNodeから削除したいfieldに対してremoveを実行
- 返されたJsonNodeからObjectNodeを生成
- 階層に応じて上記02〜03を繰り返す
ソースコード例
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode val jsonStr = """{"A":{.....}, "child":{"B":{}, "child":{....}, ....}} // 「親→子1→子2」の3世代 """.stripMargin val parentObjectNode = mapper.readTree(jsonStr).asInstanceOf[ObjectNode] val child1JsonNode = parentObjectNode.remove("child") // 戻り値としてAが返され、parentObjectNodeからchildが削除される val child1ObjectNode = mapper.readTree(childJsonNode.get(0).toString).asInstanceOf[ObjectNode] val child2JsonNode = child1ObjectNode.remove("child")
文字列を区切り文字で区切って配列にしたり等
val moji = "hoge:hohoge, geho:gegeho" val arr1 = moji.split(",") val hoge = arr1.map ( a=> { val arrlast = a.split(":") Map(arrlast(0) -> arrlast(1)) }) log.info(s"### ${hoge(0)} ###")
更に文字列の中身が数値だったらInt型に、そうでなければ文字列のままにしておく処理
val attributes = mojiretsu match { case Some(attr) => { val arr = attr.split(":") val value = try { arr(1).trim.toInt } catch { case _:NumberFormatException => arr(1).trim } Map(arr(0)->value) } case _ => Map[String, Any]() }