【问题标题】:Scala: Parse yaml file in scala (types casting )Scala:在 Scala 中解析 yaml 文件(类型转换)
【发布时间】:2018-01-04 15:53:15
【问题描述】:

我有一个 yaml 文件,我想在 scala 中读取它的内容,所以我使用 io.circe.yaml 将其解析为 json

var js = yaml.parser.parse(ymlText)
var json=js.valueOr(null)
var jsonstring=json.toString
val json2 = parse(jsonstring)

yamltext 是这样的:

ALL:
  Category1:
    Subcategory11 : 1.5
    Subcategory12 : 0
    Subcategory13 : 0
    Subcategory14  : 0.5
  Category2:
    Subcategory21 : 1.5
    Subcategory22 : 0.3
    Subcategory23 : 0
    Subcategory24  : 0

我想要过滤具有零值的子类别,我使用了以下代码:

val elements = (json2 \\"ALL" ).children.map(x=>(x.values))
var subCategories=elements.map{case(a,b)=>(b)}
var cats=elements.map{case(a,b)=>(b.asInstanceOf[Map[String,Double]])}
cats.map(x=>x.filter{case(a,b)=>b>0.0})

但最后一行给了我这个错误: scala.math.BigInt 不能转换为 java.lang.Double

【问题讨论】:

  • parseval json2 = parse(jsonString) 中的功能是什么。我想假设它是 circle.json.parser.parse,但是 circe 的 AST 没有 children 字段,所以你在底部的代码 sn-p 对这个假设没有意义。跨度>
  • 您是否检查过(例如通过打印)BigInts 在哪个阶段弹出而不是双打?当我用 circe 解析你的 yaml 时,我得到了两倍。
  • 事实上第二个解析是拥有 JValue 实例,我使用它是因为我不知道方法(right.get),Mr.SergGr 给了我正在寻找的答案。谢谢

标签: java json scala yaml


【解决方案1】:

我不确定您为什么要使用 toString + parse 以及使用哪个 parse,但您可能不需要它。此外,您没有描述您的预期结果,所以这里有一些您可能需要的猜测:

import java.io._
import io.circe._
import io.circe.yaml._
import io.circe.parser._

def test(): Unit = {
  // test data instead of a file
  val ymlText =
    """
      |ALL:
      |  Category1:
      |    Subcategory11 : 1.5
      |    Subcategory12 : 0
      |    Subcategory13 : 0
      |    Subcategory14  : 0.5
      |  Category2:
      |    Subcategory21 : 1.5
      |    Subcategory22 : 0.3
      |    Subcategory23 : 0
      |    Subcategory24  : 0
    """.stripMargin


  var js = yaml.parser.parse(new StringReader(ymlText))
  var json: Json = js.right.get

  val categories = (json \\ "ALL").flatMap(j => j.asObject.get.values.toList)
  val subs = categories.flatMap(j => j.asObject.get.toList)
  val elements: List[(String, Double)] = subs.map { case (k, v) => (k, v.asNumber.get.toDouble) }
    .filter {
      case (k, v) => v > 0.0
    }
  println(s"elements: $elements")

  val allCategories = (json \\ "ALL").flatMap(j => j.asObject.get.toList).toMap
  val filteredTree: Map[String, Map[String, Double]] = allCategories
    .mapValues(catJson => catJson.asObject.get.toList.map { case (subName, subJson) => (subName, subJson.asNumber.get.toDouble) }
      .filter { case (subName, subValue) => subValue > 0.0 }
      .toMap)
  println(s"filteredTree : $filteredTree")
}

输出结果是:

元素:List((Subcategory11,1.5), (Subcategory14,0.5), (Subcategory21,1.5), (Subcategory22,0.3))
过滤树:地图(Category1 -> Map(Subcategory11 -> 1.5,Subcategory14 -> 0.5),Category2 -> Map(Subcategory21 -> 1.5,Subcategory22 -> 0.3))

希望其中一个版本是您所需要的。

【讨论】:

  • 谢谢,我使用第二个解析的原因是有 JValue 实例,这是我知道的唯一 json 实例,所以方法 var json: Json = js.right.get 是解决方案的关键。无论如何,您的解决方案正是我正在寻找的帽子,我们的第二个猜测:)。非常感谢
猜你喜欢
  • 2015-08-31
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多