def interpolate(l:List[Tuple2[String,String]]) : List[Tuple2[java.util.Date, Long]] = {
val mapped : List[Tuple2[java.util.Date, Long]] = l.map(item => (format.parse(item._1), item._2.toLong ) )
val results = ListBuffer[Tuple2[java.util.Date, Long]]()
val last : Option[Tuple2[java.util.Date, Long]] = None
mapped.foreach( item =>
if(!last.isEmpty) {
val daysItem = item._1.getTime() / 1000 / 60 / 60 / 24
val daysLast = last.get._1.getTime() / 1000 / 60 / 60 / 24
if( daysItem - daysLast > 1 ) {
val slope = (item._2 - last.get._2) / (daysItem - daysLast)
val days = daysLast until daysItem
val missingChunk : List[Tuple2[java.util.Date, Long]] = days.map( day => (new Date(day * 24 * 60 * 60 * 1000), slope * day)).toList
results ++= missingChunk
}
}
//results += item
last = Some(item)
)
results.toList
}
错误:
<console>:45: error: value last is not a member of Any
possible cause: maybe a semicolon is missing before `value last'?
last = Some(item)
^
答案 0 :(得分:5)
这里有两个问题:
1)多个陈述需要{...}
括号:
这
mapped.foreach((item: (Date, Long)) => item
XXX // OK
YYY // NO
)
到
mapped.foreach { (item: (Date, Long)) => item
XXX // OK
YYY // OK
}
2)val
无法重新分配:
这
val last: Option[Tuple2[java.util.Date, Long]] = None
到
var last: Option[Tuple2[java.util.Date, Long]] = None
重构#1
我会尽量避免使用var
。似乎有了这个条件if (last.isDefined)
,我们可能会尝试zip
自己的列表:
scala> val l = List(1, 2, 3, 4, 5)
scala> l.zip(l.tail)
List[(Int, Int)] = List((1,2), (2,3), (3,4), (4,5))
重构你的例子:
import java.util.Date
def interpolate(l: List[(String, String)]): List[(Date, Long)] = {
val mapped: List[(Date, Long)] = l.map(item => (format.parse(item._1), item._2.toLong))
val results = ListBuffer[(Date, Long)]()
mapped.zip(mapped.tail).foreach { case ((lastDate, lastLong), (itemDate, itemLong)) =>
val daysItem = itemDate.getTime / 1000 / 60 / 60 / 24
val daysLast = lastDate.getTime / 1000 / 60 / 60 / 24
if (daysItem - daysLast > 1) {
val slope = (itemLong - lastLong) / (daysItem - daysLast)
val days = daysLast until daysItem
val missingChunk: List[(Date, Long)] = days.map(day => (new Date(day * 24 * 60 * 60 * 1000), slope * day)).toList
results ++= missingChunk
}
}
results.toList
}
重构#2
ListBuffer
是一个可变的集合。在我们的场景中,我们似乎正在尝试flatten
missingChunk
s。
继续重构:
def interpolate(l: List[(String, String)]): List[(Date, Long)] = {
val mapped: List[(Date, Long)] = l.map(item => (format.parse(item._1), item._2.toLong))
val missingChunks = mapped.zip(mapped.tail).map { case ((lastDate, lastLong), (itemDate, itemLong)) =>
val daysItem = itemDate.getTime / 1000 / 60 / 60 / 24
val daysLast = lastDate.getTime / 1000 / 60 / 60 / 24
if (daysItem - daysLast > 1) {
val slope = (itemLong - lastLong) / (daysItem - daysLast)
val days = daysLast until daysItem
days.map(day => (new Date(day * 24 * 60 * 60 * 1000), slope * day)).toList
} else List.empty[(Date, Long)]
}
missingChunks.flatten
}