【问题标题】:Scala: Refactoring a case-statement to use for-comprehensionScala:重构案例陈述以用于理解
【发布时间】:2013-06-05 15:25:39
【问题描述】:

我正在尝试将以下 Json 解析为 Scala 对象:

{
  "oneOf": [    
    { "$ref": "..." },
    { "$ref": "..." },
    { "$ref": "..." }
}

字段“oneOf”也可以是“anyOf”或“allOf”;它只是这些值之一。我正在使用 Play 的 JSON 库构建一个案例类 ComplexType。逻辑很简单;它查找给定字段并在存在时读取它,否则检查不同的字段。

(json \ "allOf") match {
    case a:JsArray => ComplexType("object", "allOf", a.as[Seq[JsObject]].flatMap(_.values.map(_.as[String])))
    case _ => 
        (json \ "anyOf") match {
            case a:JsArray => ComplexType("object", "anyOf", a.as[Seq[JsObject]].flatMap(_.values.map(_.as[String])))
            case _ =>
                  (json \ "oneOf") match {
                        case a:JsArray => ComplexType("object", "oneOf", a.as[Seq[JsObject]].flatMap(_.values.map(_.as[String])))
                        case _ => ComplexType("object", "oneOf", "Unspecified" :: Nil)
                      }
                  }
              } 

我对这种语法不满意;即使它有效,我也不明白为什么如果找不到匹配项,我需要嵌套匹配语句。我相信 for-comprehension 会很好地工作:我可以在保护子句中检查 (json \"allOf")、(json \"oneOf) 等并产生可用的结果,但不确定如何获得正确的语法。

有没有更优雅的方式来构建这个案例类?

谢谢,

迈克

【问题讨论】:

    标签: json scala refactoring playframework-2.0


    【解决方案1】:

    我不认为理解在这里有用。

    您可以使用这样的自定义提取器使您的代码更具可读性:

    class Extractor(s: String) {
      def unapply(v: JsValue): Option[JsArray] = json \ s match {
        case a: JsArray => Some(a)
        case _ => None
      }
    }
    
    val AllOf = new Extractor("allOf")
    val AnyOf = new Extractor("anyOf")
    val OneOf = new Extractor("oneOf")
    
    val (name, es) = json match {
        case AllOf(a) => "allOf" -> Some(a)
        case AnyOf(a) => "anyOf" -> Some(a)
        case OneOf(a) => "oneOf" -> Some(a)
        case _ => "oneOf" -> None
      }
    val result =
      es.
        map{ a => ComplexType("object", name, a.as[Seq[JsObject]].flatMap(_.values.map(_.as[String]))) }.
        getOrElse("Unspecified" :: Nil)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 2010-10-30
      • 2016-05-13
      • 2016-02-21
      • 1970-01-01
      相关资源
      最近更新 更多