Вот один из способов сделать это.Я бы порекомендовал разделить все, что вы делаете, на множество небольших, простых в управлении функций, иначе вы потеряетесь, пытаясь выяснить, где что-то идет не так, если все это начнет вызывать исключения.Настройка данных:
val array = Array("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")
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
)
Функция для преобразования Array[String]
в Array[List[String]]
и обработки любых пустых полей (здесь я предположил, что вы хотите, чтобы пустые поля были 0
. Измените это при необходимости):
def splitArray(arr: Array[String]): Array[List[String]] = {
arr.map(
_.replaceAll("\\$", "") // Remove $
.split(",") // Split by ,
.map {
case x if x.isEmpty => "0" // If empty
case y => y // If not empty
}
.toList
)
}
Функция для превращения List[String]
в StockPrice
.Обратите внимание, что это упадет, если список не будет длиной 16 пунктов.Я оставлю тебя, чтобы справиться с этим.Кроме того, имена довольно не описательные, так что вы тоже можете это изменить.Они также упадут, если ваши данные не будут сопоставлены с соответствующими .toDouble
или toByte
или чем-то еще - вы можете справиться и с этим сами:
def toStockPrice: List[String] => StockPrice = {
case a :: b :: c :: d :: e :: f :: g :: h :: i :: j :: k :: l :: m :: n :: o :: p :: Nil =>
StockPrice(a.toByte, b, c, d.toDouble, e.toDouble, f.toDouble, g.toDouble, h.toDouble, i.toDouble, j.toDouble,
k.toDouble, l.toDouble, m.toDouble, n.toDouble, o.toDouble, p.toDouble)
}
Хорошая функция, чтобы собрать все это вместе:
def makeCaseClass(arr: Array[String]): Seq[StockPrice] = {
val splitArr: Array[List[String]] = splitArray(arr)
splitArr.map(toStockPrice)
}
Вывод:
println(makeCaseClass(array))
//ArraySeq(
// StockPrice(1,AA,1/7/2011,15.82,16.72,15.78,16.42,2.39655616E8,3.79267,0.0,0.0,16.71,15.97,-4.42849,26.0,0.182704),
// StockPrice(1,AA,1/14/2011,16.71,16.71,15.64,15.97,2.42963398E8,-4.42849,1.380223028,2.39655616E8,16.19,15.79,-2.47066,19.0,0.187852),
// StockPrice(1,AA,1/21/2011,16.19,16.38,15.6,15.79,1.38428495E8,-2.47066,-43.02495926,2.42963398E8,15.87,16.13,1.63831,12.0,0.189994),
// StockPrice(1,AA,1/28/2011,15.87,16.63,15.82,16.13,1.51379173E8,1.63831,9.355500109,1.38428495E8,16.18,17.14,5.93325,5.0,0.185989)
//)
Редактировать:
Объяснить бит a :: b :: c .....
- это способприсвоение имен элементам списка или последовательности, если вы знаете размер списка.
val ls = List(1, 2, 3)
val a :: b :: c :: Nil = List(1, 2, 3)
println(a == ls.head) // true
println(b == ls(1)) // true
println(c == ls(2)) // true
Обратите внимание, что значение Nil
важно, поскольку оно означает, что последний элемент списка равен Nil.Без него c
будет равно List(3)
, так как остальная часть любого List назначена последнему значению в вашем определении.
Вы можете использовать это в сопоставлении с образцом, как и я, чтобы что-то сделатьс результатами:
val ls = List(1, "b", true)
ls match {
case a :: b :: c if c == true => println("this will not be printed")
case a :: b :: c :: Nil if c == true => println(s"this will get printed because c == $c")
} // not exhaustive but you get the point
Вы также можете использовать его, если знаете, каким должен быть каждый элемент списка, например:
val personCharacteristics = List("James", 26, "blue", 6, 85.4, "brown")
val name :: age :: eyeColour :: otherCharacteristics = personCharacteristics
println(s"Name: $name; Age: $age; Eye colour: $eyeColour")
// Name: James; Age: 26; Eye colour: blue
Очевидно, что эти примеры довольно тривиальныи не совсем то, что вы видите как профессиональный разработчик Scala (по крайней мере, я так не думаю), но это очень удобно, поскольку я все еще иногда использую этот синтаксис ::
на работе.