2015-10-07 4 views
1

Вот мой кодКак создать класс case из списка [String]?

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")?

+2

Использование значимых типов сделает вашу жизнь намного лучше, я обещаю. –

+0

Спасибо @TravisBrown, я второй, я их изменю – daydreamer

+0

От имени, похоже, несколько групп из них связаны. Вероятно, у них должны быть свои собственные классы case, а blueCoatEvent состоит из одного из них + то, что осталось. –

ответ

-1
object BlueCoatEvent { 
    def apply(strings: Seq[String]): BlueCoatEvent = BlueCoatEvent(
    strings(0), 
    strings(1), 
    strings(2), 
    strings(3), 
    strings(4), 
    strings(5), 
    strings(6), 
    strings(7), 
    strings(8), 
    strings(9), 
    strings(10), 
    strings(11), 
    strings(12), 
    strings(13), 
    strings(14), 
    strings(15), 
    strings(16), 
    strings(17), 
    strings(18), 
    strings(19), 
    strings(20), 
    strings(21), 
    strings(22), 
    strings(23), 
    strings(24), 
    strings(25)) 
} 

BlueCoatEvent(s.split("\\s")) 
+0

По какой-то причине я не думаю, что это то, что имел в виду OP ... –

+0

Кажется, это похоже на то, что их класс case Case BlueCoatEvent выглядит. –

0

Уродливый ужасный способ заключается в следующем:

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, если вы не используете небезопасный способ или какое-то генерирование кода.

0

Другой подход путем определения Map[String,String] над значениями события; пусть

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

и

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

Тогда из

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

мы можем получать значения свойств для данного stringisizedBlueCoatEvent.

Смежные вопросы