Scala中复杂的多维列表操作

Kam*_*mil -2 scala slice collect

给出如下列表:

val dane = List(
    ("2011-01-04", -137.76),
    ("2011-01-04", 2376.45),
    ("2011-01-04", -1.70),
    ("2011-01-04", -1.70),
    ("2011-01-04", -1.00),
    // ... skip a few ...
    ("2011-12-22", -178.02),
    ("2011-12-29", 1800.82),
    ("2011-12-23", -83.97),
    ("2011-12-24", -200.00),
    ("2011-12-24", -30.55),
    ("2011-12-30", 728.00)
)
Run Code Online (Sandbox Code Playgroud)

我想01按照指定的顺序使用以下操作对特定月份(例如1月或1月)的值(即内部列表的第二项)求和:

  1. groupBy
  2. slice
  3. collect
  4. sum

Kev*_*ght 11

我感觉相反,所以这里是一个使用的规定的方法NONE答案:groupBy,slice,collect或者sum

避免collect是最困难的部分,condOpt/这flatten是多么丑陋......

val YMD = """(\d\d\d\d)-(\d\d)-(\d\d)""".r

import PartialFunction._

(dane map {
  condOpt(_:(String,Double)){ case (YMD(_,"01",_), v) => v }  
}).flatten reduceLeft {_+_}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ith 8

(for((YearMonthDay(_, 1, _), value)<-dane) yield value).sum

object YearMonthDay{
   def unapply(dateString:String):Option((Int, Int, Int)) ={ 
       //yes, there should really be some error checking in this extractor 
       //to return None for a bad date string
       val components = dateString.split("-")
       Some((components(0).toInt, components(1).toInt, components(2).toInt)) 
  }  

}
Run Code Online (Sandbox Code Playgroud)


Rex*_*err 5

既然凯文已经开始出现相反答案的趋势,那么这是你永远不应该使用的一个,但天哪,它有效!(并且避免使用所有请求的方法,如果更改字符串,它将在任何月份工作,但它确实要求按日期对列表进行排序.)

dane.scanLeft(("2011-01",0.0))((l,r) =>
  ( l._1,
    if ((l._1 zip r._1).forall(x => x._1==x._2)) l._2+r._2 else 0.0
  )
).dropWhile(_._2==0).takeWhile(_._2 != 0.0).reverse.head._2
Run Code Online (Sandbox Code Playgroud)