![[Scala]Circeでリストの各要素をパースの成否ごとに蓄積する](https://devio2023-media.developers.io/wp-content/uploads/2019/06/scala_eye_catch.png)
[Scala]Circeでリストの各要素をパースの成否ごとに蓄積する
Circeでリストの各要素を個別にパースして成否別に取り出すデコーダーを導出しました。
2024.02.17
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
リスト内に複数の要素を含むJSONをパースする際に、いくつかの要素のパースに失敗してもそれ以外の要素のパースに成功する場合は成功したものだけを取り出したい場合があります。 Circeでパーサーを合成すると簡単にできるので試してみました。
やりたいこと
入力のJSONは下記のようなものです。この例では3番目の要素のname
の型が正しくありません。
[
{ "name": "nyan"},
{ "name": "miaou"},
{ "name": 1234},
{ "name": "miaou"}
]
このJSONをパースした結果以下のようなリストを得たいです。
final case class Cat(name: String)
List(
Right(value = Cat(name = "nyan")),
Right(value = Cat(name = "meow")),
Left(value = DecodingFailure at .name: Got value '1234' with wrong type, expecting string),
Right(value = Cat(name = "miaou"))
) // List[Either[ParsingFailure, Cat]]
またエラーとパース済み値を別々のリストで受け取りたいです。
(
List(DecodingFailure at .name: Got value '1234' with wrong type, expecting string),
List(Cat(name = "miaou"), Cat(name = "meow"), Cat(name = "nyan"))
) //(List[DecodingFailure], List[Cat])
コード
既存のデコーダーを使ってそれぞれのデコーダーを導出できます。
出力
Right(
value = (
List(DecodingFailure at .name: Got value '1234' with wrong type, expecting string),
List(Cat(name = "miaou"), Cat(name = "meow"), Cat(name = "nyan"))
)
)
まとめ
リストの要素をパースの成否ごとに分割できるデコーダーを導出しました。