1

Here is my code

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> 

How do I create blueCoatEvent from s.split("\\s")?

daydreamer
  • 87,243
  • 191
  • 450
  • 722

3 Answers3

2
  1. See answer in Instantiating a case class from a list of parameters

  2. Introduce meaningsful sub-types/case classes and compose BlueCoatEvent with them.

Community
  • 1
  • 1
Martin Senne
  • 5,939
  • 6
  • 30
  • 47
1

The ugly horrible way is this:

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)

You can use any way you want to convert from collection to TupleN:

I picked toTuple from there.

This is unsafe, ugly and does not save you much. You can resort to code generation, reflection or macros to get something more helpful.

Another option:

Based on this idea Applying an argument list to curried function using foldLeft in Scala we can use A.curried with HList to produce a cleaner solution:

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)
}

The problem again is that you can't get away from spelling out the types whether those are Tuple or HList unless you go unsafe way or some sort of code generation.

Community
  • 1
  • 1
yǝsʞǝla
  • 16,272
  • 2
  • 44
  • 65
0

A different approach by defining a Map[String,String] over the values of an event; let

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

and

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

Then from

EventMap( fields(BlueCoatEvent) zip s.split("\\s") toMap )

we can fetch values properties for a given stringisized BlueCoatEvent.

elm
  • 20,117
  • 14
  • 67
  • 113