I have created a case class like this:
def case_class(): Unit = {
case class StockPrice(quarter : Byte,
stock : String,
date : String,
open : Double,
high : Double,
low : Double,
close : Double,
volume : Double,
percent_change_price : Double,
percent_change_volume_over_last_wk : Double,
previous_weeks_volume : Double,
next_weeks_open : Double,
next_weeks_close : Double,
percent_change_next_weeks_price : Double,
days_to_next_dividend : Double,
percent_return_next_dividend : Double
)
And I have thousands of line as Array of String like this:
1,AA,1/7/2011,$15.82,$16.72,$15.78,$16.42,239655616,3.79267,,,$16.71,$15.97,-4.42849,26,0.182704
1,AA,1/14/2011,$16.71,$16.71,$15.64,$15.97,242963398,-4.42849,1.380223028,239655616,$16.19,$15.79,-2.47066,19,0.187852
1,AA,1/21/2011,$16.19,$16.38,$15.60,$15.79,138428495,-2.47066,-43.02495926,242963398,$15.87,$16.13,1.63831,12,0.189994
1,AA,1/28/2011,$15.87,$16.63,$15.82,$16.13,151379173,1.63831,9.355500109,138428495,$16.18,$17.14,5.93325,5,0.185989
How Can I parse data from Array into that case class? Thank you for your help!
You can proceed as below (I've taken simplified example)
Given your case class and data (lines)
Note: you can read lines from a text file as
You can have some utility methods for mapping (cleaning & parsing)
And then use them to convert strings into case-class objects
As a more advanced (and generalized) approach, you can generate the mapping (parsing) function for converting tokens into fields of your case-class using something like
reflection
, as told hereHere's one way of doing it. I'd recommend splitting everything you do up into lots of small, easy-to-manage functions, otherwise you will get lost trying to figure out where something is going wrong if it all starts throwing exceptions. Data setup:
Function to turn
Array[String]
intoArray[List[String]]
and handle any empty fields (I've made an assumption here that you want empty fields to be0
. Change this as necessary):Function to turn a
List[String]
into aStockPrice
. Note that this will fall over if the List isn't exactly 16 items long. I'll leave you to handle any of that. Also, the names are pretty non-descriptive so you can change that too. It will also fall over if your data doesn't map to the relevant.toDouble
ortoByte
or whatever - you can handle this yourself too:A nice function to bring this all together:
Output:
Edit:
To explain the
a :: b :: c .....
bit - this is a way of assigning names to items in a List or Seq, given you know the List's size.Note that the
Nil
is important because it signifies the last element of the List being Nil. Without it,c
would be equal toList(3)
as the rest of any List is assigned to the last value in your definition.You can use this in pattern matching as I have in order to do something with the results:
You can also use it if you know what you want each element in the List to be, like this:
Obviously these examples are pretty trivial and not exactly what you'd see as a professional Scala developer (at least I don't), but it's a handy thing to be aware of as I do still use this
::
syntax at work sometimes.