现有集合:
var m2 = Map("name" -> "wang" ,"sex" -> "1" ,"dep" -> "it" ,"salary" -> 2000) var list3 = List(m2 ,m2 ,Map("name" -> "yi" ,"sex" -> "0" ,"dep" -> "hr" ,"salary" -> 2000))从上面的代码中可以看出,我模拟了数据库中有 name、sex、dep、salary 这四个字段的表结构。
例如,我想求每个人的工资,我思路如下所示:
提取有效的字段,即 name、salary,这里使用到了 map 函数,结果是类似 List[(Some(String),Some(Int)]依据 name 进行分组,这里使用了 groupby 函数,结果是 Map[Some(String),List[(Some(String),Some(Int)]]分组之后,得到一个 Map,而 Map 中的 value 值是一个 List,对 List 进行字段抽取,只保留 salary对 salary 进行 sum 计算具体的代码如下所示:
// func1 负责提取使用到的字段:name、salary var func1 = (x:Map[String,Any])=>{(x.get("name"),x.get("salary"))} // func3 负责将 salary 进行汇总 val func3 = (y:List[Int])=>{y.sum} val rs1 = list3.map(func1) .groupBy(_._1) .mapValues(_.map(_._2.get.asInstanceOf[Int])) .mapValues(func3)总结:
list + map 这种方式可以用来替代 web 开发中 JavaBean 的作用在这种类似链式编程的过程中会,scala 的编译器会对数据的类型向上转型,例如,字段抽取后,List[(Some(String),Some(Int)] 如果,想要保留住字段的类型,可以使用 get.asInstanceOf[类型],来明确的指定数据类型以后就是在编写类似的代码的时候,一定参考编译器的类型提示来编写代码,因为他会帮我们找到正确的数据类型作为函数的参数最后,再对应用场景做一下延伸,对有 n 指标的 m 个数值进行求和,代码如下:
val rs10 =List(("wang","1","it",100,98) ,("wang","0","it",200,98) ,("wang","1","it",400,98) ,("wang","1","it",500,98) ).map((x:(String,String,String,Int,Int))=>{(x._1+x._2,x._4,x._5)}) val func13 = (x:List[(String,Int,Int)])=>{x.map((a:((String,Int,Int))) =>{(a._2,a._3)})} println(rs10.groupBy(_._1) .mapValues(func13) .mapValues((x:List[(Int,Int)])=>{x.reduce((a:((Int,Int)),b:((Int,Int))) =>{(a._1+b._1,a._2+b._2)})}))最后的最后, 其实可以对 n 指标的 m 个数值进行平均值、最大、最小、rownumber 的计算,这个就需要使用单独的编写递归函数了。