scala-具有动态字段数的文本解析的等效case类

scala-具有动态字段数的文本解析的等效case类,scala,Scala,我从一个进程收到一条消息,我正试图将它映射到一个case类。消息位于管道符号内,由逗号分隔,如下所示 |id1,5,2010-06-19,27.40,2010-06-20,35.40,2010-06-21,8.50,2010-06-22,23.40,2010-06-23,57.40,TX5| 这封信是这样包装的 1.id 2.3和4同时出现的次数 3.date//它与基于2的4一起重复 4.amount//它与基于2的3一起重复 5.code——最后一个字段 虽然高级别有5个字段,但3和4可以

我从一个进程收到一条消息,我正试图将它映射到一个case类。消息位于管道符号内,由逗号分隔,如下所示

|id1,5,2010-06-19,27.40,2010-06-20,35.40,2010-06-21,8.50,2010-06-22,23.40,2010-06-23,57.40,TX5|
这封信是这样包装的

1.id

2.3和4同时出现的次数

3.date//它与基于2的4一起重复

4.amount//它与基于2的3一起重复

5.code——最后一个字段

虽然高级别有5个字段,但3和4可以在2的基础上重复

为了更好地理解,这里还有一些示例

|id2,7,2010-06-19,56.40,2010-06-20,23.76,2010-06-21,12.50,2010-06-22,87.12,2010-06-23,52.90,2010-06-24,35.70,2010-06-25,72.80,TX3|
|id3,4,2010-06-19,87.40,2010-06-20,32.40,2010-06-21,21.50,2010-06-22,73.40,TX2|
|id4,6,2010-06-19,56.12,2010-06-20,66.43,2010-06-21,23.12,2010-06-22,87.12,2010-06-23,34.90,2010-06-24,55.00,FT3|
我可以从开始和结束处删除管道符号。。解析并获取第一个和最后一个字段

scala> val str="id1,5,2010-06-19,27.40,2010-06-20,35.40,2010-06-21,8.50,2010-06-22,23.40,2010-06-23,57.40,TX5"
str: String = id1,5,2010-06-19,27.40,2010-06-20,35.40,2010-06-21,8.50,2010-06-22,23.40,2010-06-23,57.40,TX5

scala> val (id,code) = (str.split(",")(0), str.split(",").last)
id: String = id1
code: String = TX5

scala>
但是我如何将其余的映射到一个case类中呢


请注意,这与消息具有固定列数且可以轻松映射到case类的情况不同

您尚未指定case类的外观。这里有一种方法可以合理地容忍任何格式不良的输入数据字符串

case class CC(id        :String
             ,datePrice :Seq[(String,Double)]
             ,code      :String)

import util.Try
def mkCC(dataStr :String) :CC = {
  val dataArr = dataStr.split(",")
  val id      = dataArr.head.filter('|'.!=)
  val code    = dataArr.last.filter('|'.!=)
  val dps     = Try{
    val len = dataArr(1).toInt
    Seq.range(2, len*2+2, 2)
       .flatMap(idx => Try{(dataArr(idx),dataArr(idx+1).toDouble)}.toOption)
  }.getOrElse(Seq())
  CC(id, dps, code)
}
用法:

val data1="|id2,7,2010-06-19,56.40,2010-06-20,23.76,2010-06-21,12.50,2010-06-22,87.12,2010-06-23,52.90,2010-06-24,35.70,2010-06-25,72.80,TX3|"
val data2="|id3,4,2010-06-19,87.40,2010-06-20,32.40,2010-06-21,21.50,2010-06-22,73.40,TX2|"
val data3="|id4,6,2010-06-19,56.12,2010-06-20,66.43,2010-06-21,23.12,2010-06-22,87.12,2010-06-23,34.90,2010-06-24,55.00,FT3|"

val cc1 :CC = mkCC(data1)
val cc2 :CC = mkCC(data2)
val cc3 :CC = mkCC(data3)

这个问题和。。因为数组是线性的且大小固定。这解决了解析。。。但是,是否可以将datePrice转换为一种JSON数组?。。因为我应该能够使用类似datePrice.date[0]或datePrice.Price[1]之类的CC,而不是使用._1、._2…您可以创建一个单独的类来代替元组,
datePrice(日期:字符串,价格:双精度)
。访问权限可能类似于
cc3.pds(4).date
cc9.pds(0).price
。或者您可以选择加载两个单独的阵列。访问权限看起来像是
cc2.date(5)
cc1.price(6)
。无论哪种方式,解析/加载代码都不会与前面的编码示例有太大的不同。