8

ここで「スタイル」または「効果的なスカラ」タイプの質問があります。Json in Play フレームワークにシリアル化する必要がある「FeatureCheck」クラスがあります。

case class FeatureCheck(val result: Option[Boolean], val missing: Option[Array[String]], val error: Option[String])

独自の「書き込み」を使用してシリアル化していますが、コードは Java コードによく似ています。チェックオブジェクトの各オプションが定義されている場合にのみシリアル化したいと思います (最終オブジェクトには空の値があってはなりません)。

def writes(check: FeatureCheck): JsValue = {
  val builder = Seq.newBuilder[(String, JsValue)]
  if (check.error.isDefined) {
    builder += "error" -> JsString(check.error.get)
  }
  if (check.missing.isDefined) {
    builder += "missing" -> Json.toJson(check.missing.get)
  }
  if (check.result.isDefined) {
    builder += "result" -> JsBoolean(check.result.get)
  }
  JsObject(builder.result)
}

そのため、これらの醜いif-thenを使用せずに、またはシーケンスのビルダーを削除することさえせずにこれを行う方法があるかどうか疑問に思っていました.

助けやコメントをありがとう。

説明:

result = true だけを送信したいとしましょう。結果の Json は次のようになります。

{"result":true} 

ではない

{
    "result": true,
    "error": null,
    "missing": []
}
4

3 に答える 3

6

単純にオプションを seq に追加できることを考えると (値が null でない場合にリストに追加を参照)、必要なことをかなりエレガントに行うことができます。

type JsField = (String, JsValue)
def writes(check: FeatureCheck): JsValue = {
  JsObject(
    Seq[JsField]() ++
    check.error.map("error" -> JsString(_)) ++
    check.missing.map("missing" -> Json.toJson(_)) ++
    check.result.map("result" -> JsBoolean(_))    
  )
}
于 2013-04-29T13:27:15.053 に答える
4

追加のチェックをスキップできます。isDefinedオプションの値が であるかどうかのみがチェックされますSome。はin scalagetOrElseに対して同じことを実行します。Option

これはやや単純なバージョンです。

def writes(check: FeatureCheck): JsValue = {
  val builder = Seq.newBuilder[(String, JsValue)]
  builder += "error" -> JsString(check.error.getOrElse(""))
  builder += "missing" -> Json.toJson(check.missing.getOrElse({ Array[String]() }))
  builder += "result" -> JsBoolean(check.result.getOrElse(false))
  JsObject(builder.result)
}

そして、これはさらに単純であると考えられます。

def writes(check: FeatureCheck): JsValue = JsObject(
  List(
    "error" -> JsString(check.error.getOrElse("")),
    "missing" -> Json.toJson(check.missing.getOrElse({ Array[String]() })),
    "result" -> JsBoolean(check.result.getOrElse(false))
  )
)

編集

プロパティが存在しない場合にプロパティを追加したくない場合は、これがよりエレガントだと思います:

def writes(check: FeatureCheck): JsValue = JsObject(
  List(
    check.error.map("error" -> JsString(_)),
    check.missing.map("missing" -> Json.toJson(_)),
    check.result.map("result" -> JsBoolean(_))
  ).flatten
)
于 2013-04-29T12:37:01.767 に答える