0

如何使用函数式编程范式删除以下代码片段中的“var”,我试图将 json 字符串解析为 map[String,Object],如果失败,我将其解析为 map[Long,Object] ,所以'KEY_TYPE'只是一个开关,我如何在函数式编程中实现开关逻辑?

   var KEY_TYPE = "String"

  /**
    * 解析json格式 先尝试一次解析成Map[String,Object] 失败则解析成Map[Long,Object]
    *
    * @param runSnap
    * @return
    */
  def parseJson(runSnap: String): Map[Long, Object] = {
    Try {
      if (KEY_TYPE == "String") {
        JSONUtils.parseByFastJson(runSnap).asScala
          .toMap.map(entry => entry._1.toLong -> entry._2)
      } else {
        JSONUtils.parseByFastJsonLongKey(runSnap).asScala
          .toMap.map(entry => Long2long(entry._1.toLong) -> entry._2)
      }
    } match {
      case Success(result) => result
      case Failure(exception) => {
        println("json parse excepiton " + exception)
        if (KEY_TYPE == "String") {
          KEY_TYPE = "Long"
          parseJson(runSnap)
        } else {
          Map[Long, Object]()
        }
      }
    }
  }
4

3 回答 3

0

是不是像下面这样:

def parseJson(runSnap: String): Map[Long, Object] = {
   Try(JSONUtils.parseByFastJson(runSnap).asScala .toMap.map(entry => entry._1.toLong -> entry._2))
   .toOption
   .orElse(Try(JSONUtils.parseByFastJsonLongKey(runSnap).asScala).toOption)
   .getOrElse( Map[Long, Object]())
}
于 2018-05-28T07:00:26.370 回答
0

这是您的代码的功能更强大的版本。它定义了一个带有apply方法的对象,该方法可以像原始函数一样使用。

object parseJson {
  private def parseAsString(runSnap: String): Map[Long, Object] =
    Try {
      JSONUtils.parseByFastJson(runSnap).asScala
        .toMap.map(entry => entry._1.toLong -> entry._2)
    } match {
      case Success(result) =>
        result
      case _ =>
        parser = parseAsLong _

        parser(runSnap)
    }

  private def parseAsLong(runSnap: String): Map[Long, Object] =
    Try {
      JSONUtils. parseByFastJsonLongKey(runSnap).asScala
        .toMap.map(entry => Long2long(entry._1.toLong) -> entry._2)
    }.getOrElse(Map[Long, Object]())


  private val parser = parseAsString _

  def apply(runSnap: String) = parser(runSnap)
}

最初parser设置为parseAsStringso applycalls parseAsStringwhich calls parseByFastJson。但是当解析失败时,parseAsString它设置parserparseAsLong. 随后的调用apply将改为调用parseAsLong哪个调用parseByFastJsonLongKey。唯一一次调用两个 JSON 函数是第一次parseByFastJson失败。之后,parseByFastJsonLongKey由 直接调用parseAsLong

使用一个对象可以使var隐藏起来,并且在其中存储一个函数varString每次测试一个更清洁和更有效。

于 2018-05-28T11:07:12.240 回答
0
  1. 不要使用魔术字符串,这很容易出错。定义一些枚举,或者至少使用Boolean. 我将Boolean用于KEY_TYPE.
  2. 只需KEY_TYPE作为(默认)参数传递:

    def parseJson(runSnap: String, keyTypeIsString: Boolean = true): 
    Map[Long, Object] = {
      Try {
        if (keyTypeIsString) {
          JSONUtils.parseByFastJson(runSnap).asScala
            .toMap.map(entry => entry._1.toLong -> entry._2)
        } else {
          JSONUtils.parseByFastJsonLongKey(runSnap).asScala
            .toMap.map(entry => Long2long(entry._1.toLong) -> entry._2)
        }
      } match {
        case Success(result) => result
        case Failure(exception) => {
          println("json parse excepiton " + exception)
          if (keyTypeIsString) {
            parseJson(runSnap, false)
          } else {
            Map[Long, Object]()
          }
        }
      }
    }
    
于 2018-05-28T06:23:56.553 回答