这是我的代码
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")
?
答案 0 :(得分:2)
介绍有意义的子类型/案例类,并用它们组成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)
}
问题再次出现,除非你采用不安全的方式或某种代码生成方式,否则你无法完全解析这些类型Tuple
或HList
。
答案 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 )
的值属性。