2012年10月18日木曜日

[Scala] JSON の標準パーサーで数値型が Double になる問題への対処方法

前回、Scala の JSON 標準ライブラリを使ってみた。 Scala の 標準パーサーでは、数値型が常に Double として扱われてしまう問題がある。
  val text = """{ "x":1 }""";
  val result = JSON.parseFull(text);
  val map = result.get.asInstanceOf[Map[String, Option[Any]]];
  println (map.get("x").get);

--------------------
1.0
scala.util.parsing.json.Parser クラスで
  // Global default number parsing function
  protected var defaultNumberParser : NumericParser = {_.toDouble}
と定義されているので、数値が常に String.toDouble とパースされてしまうのが原因。

scala.util.parsing.json.JSON オブジェクトには 数値パーサを変更するメソッドが用意されている。
  def globalNumberParser_=(f: NumericParser) 
      { defaultNumberParser = f }
これを使うことで Int 型と Double 型を切り替えて解釈するようにできる。
  JSON.globalNumberParser = (in) => 
      {try in.toInt catch {case _ => in.toDouble}}

  val text = """{ "x":1, "y":1.0 }""";
  val result : Option[Any] = JSON.parseFull(text);
  val map = result.get.asInstanceOf[Map[String, Option[Any]]];
  println ("x: " + map.get("x").get);
  println ("y: " + map.get("y").get);

--------------------
x: 1
y: 1.0

ちなみに、「def globalNumberParser_=(f: NumericParser) 」は、 「globalNumberParser_=」がメソッド名。 Scala では、「XXXXX_=(引数)」形式の関数は「XXX = 引数」という代入形式で呼び出せるというルールがある。
一見わかりにくいので注意。

0 件のコメント:

コメントを投稿