2015-12-16 18 views
0
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 
} 

錯誤的成員:Scala中不不限

<console>:45: error: value last is not a member of Any 
possible cause: maybe a semicolon is missing before `value last'? 
      last = Some(item) 
      ^
+1

'last'是'val'。你不能重新分配它的價值。 – jwvh

+0

您可能想要查看nscala-time來簡化一些日期操作。 – Daenyth

回答

5

有2個問題這裏:

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是一個可變的集合。在我們的情況下,似乎我們正在嘗試flattenmissingChunk 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 
    } 
+0

而不是用自己的尾巴壓縮,你可以使用['sliding'](http://www.scala-lang.org/api/current/index.html#[email protected](size:Int,step的:int):迭代[REPR]) – Daenyth