如何从List [String]创建案例类?

时间:2015-10-07 21:19:20

标签: scala

这是我的代码

scala> s
res6: String = 2005-05-06 14:58:56 192 45.14.5.238 200 TCP_NC_MISS 1123 496 GET http c4.maxserving.com /gen.js ?site=5835&area=side_ros&group=sidebar&PageID=33364329499 - DIRECT c4.maxserving.com application/x-javascript "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)" PROXIED Web%20Advertisements - 192.16.170.44 SG-HTTP-Service - none -

scala> s.split("\\s")
res7: Array[String] = Array(2005-05-06, 14:58:56, 192, 45.14.5.238, 200, TCP_NC_MISS, 1123, 496, GET, http, c4.maxserving.com, /gen.js, ?site=5835&area=side_ros&group=sidebar&PageID=33364329499, -, DIRECT, c4.maxserving.com, application/x-javascript, "Mozilla/4.0, (compatible;, MSIE, 6.0;, Windows, NT, 5.1;, SV1;, .NET, CLR, 1.1.4322)", PROXIED, Web%20Advertisements, -, 192.16.170.44, SG-HTTP-Service, -, none, -)

scala> case class BlueCoatEvent(date: String,
     |                          time: String,
     |                          timeTaken: String,
     |                          cIp: String,
     |                          scStatus: String,
     |                          sAction: String,
     |                          scBytes: String,
     |                          csBytes: String,
     |                          csMethod: String,
     |                          csUriScheme: String,
     |                          csHost: String,
     |                          csUriPath: String,
     |                          csUriQuery: String,
     |                          csUsername: String,
     |                          sHierarchy: String,
     |                          sSupplierName: String,
     |                          rsContentType: String,
     |                          csUserAgent: String,
     |                          scFilterResult: String,
     |                          scFilterCategory: String,
     |                          xVirusId: String,
     |                          sIp: String,
     |                          sSiteName: String,
     |                          xVirusDetails: String,
     |                          xIcapErrorCode: String,
     |                          xIcapErrorDetails: String)
defined class BlueCoatEvent

scala> 

如何从blueCoatEvent创建s.split("\\s")

3 个答案:

答案 0 :(得分:2)

  1. 请参阅Instantiating a case class from a list of parameters

  2. 中的回答
  3. 介绍有意义的子类型/案例类,并用它们组成BlueCoatEvent

答案 1 :(得分:1)

丑陋的可怕方式是:

scala>   case class A(x: String, y: String, z: String)
defined class A

scala>   def toTuple[A <: Object](as:List[A]):Product = {
     |     val tupleClass = Class.forName("scala.Tuple" + as.size)
     |     tupleClass.getConstructors.apply(0).newInstance(as:_*).asInstanceOf[Product]
     |   }
toTuple: [A <: Object](as: List[A])Product

scala>   val l = List("a", "b", "c")
l: List[String] = List(a, b, c)

scala>   val t3 = toTuple(l).asInstanceOf[Tuple3[String, String, String]]
t3: (String, String, String) = (a,b,c)

scala>   val f = A.tupled
f: ((String, String, String)) => A = <function1>

scala>   f(t3)
res0: A = A(a,b,c)

您可以使用任何想要从集合转换为TupleN的方式:

我从那里选了toTuple

这是不安全的,丑陋的并且不会为你节省太多。您可以使用代码生成,反射或宏来获得更多帮助。

另一种选择:

根据这个想法Applying an argument list to curried function using foldLeft in Scala,我们可以A.curried使用HList来制作更清晰的解决方案:

object CaseClassFromList extends App {

  sealed trait HList

  final case class HCons[H, T <: HList](head : H, tail : T) extends HList {
    def ::[H1](h : H1) = HCons(h, this)
    override def toString = head+" :: "+tail.toString
  }

  trait HNil extends HList {
    def ::[H1](h : H1) = HCons(h, this)
    override def toString = "HNil"
  }

  case object HNil extends HNil
  type ::[H, T <: HList] = HCons[H, T]


  trait FoldCurry[L <: HList, F, Out] {
    def apply(l : L, f : F) : Out
  }

  // Base case for HLists of length one
  implicit def foldCurry1[H, Out] = new FoldCurry[H :: HNil, H => Out, Out] {
    def apply(l : H :: HNil, f : H => Out) = f(l.head)
  }

  // Case for HLists of length n+1
  implicit def foldCurry2[H, T <: HList, FT, Out]
  (implicit fct : FoldCurry[T, FT, Out]) = new FoldCurry[H :: T, H => FT, Out] {
    def apply(l : H :: T, f : H => FT) = fct(l.tail, f(l.head))
  }

  // Public interface ... implemented in terms of type class and instances above
  def foldCurry[L <: HList, F, Out](l : L, f : F)
                                   (implicit fc : FoldCurry[L, F, Out]) : Out = fc(l, f)


  case class A(x: String, y: String, z: String)

  //val l = List("a", "b", "c")
  val lh = "a" :: "b" :: "c" :: HNil

  val newA = foldCurry(lh, A.curried)

  println(newA)
}

问题再次出现,除非你采用不安全的方式或某种代码生成方式,否则你无法完全解析这些类型TupleHList

答案 2 :(得分:0)

通过在事件的值上定义config来采用不同的方法;让

Map[String,String]

case class EventMap( data: Map[String,String])

然后从

def fields(cc: Product) = cc.getClass.getDeclaredFields.map(_.getName)

我们可以获取给定 stringisized EventMap( fields(BlueCoatEvent) zip s.split("\\s") toMap ) 的值属性。