paw*_*ior 2 scala group-by list
基本上我不是真正的Java/Scala粉丝,但不幸的是我被迫用它来学习.无论如何,我得到了一个任务:
程序得到的是一系列对象,如:Mark(val name String, val style_mark Int, val other_mark Int).
如何使用groupBy,按名称对标记进行分组,并获得style_mark和other_mark的平均值?
Mark("John", 2, 5)
Mark("Peter", 3, 7)
Mark("John", 4, 3)
Run Code Online (Sandbox Code Playgroud)
应该返回:
Mark("John", 3, 4)
Mark("Peter", 3, 7)
Run Code Online (Sandbox Code Playgroud)
这是代码:
class Mark(val name: String, val style_mark: Int, val other_mark: Int) {}
object Test extends Application
{
val m1 = new Mark("Smith", 18, 16);
val m2 = new Mark("Cole", 14, 7);
val m3 = new Mark("James", 13, 15);
val m4 = new Mark("Jones", 14, 16);
val m5 = new Mark("Richardson", 20, 19);
val m6 = new Mark("James", 4, 18);
val marks = List(m1, m2, m3, m4, m5, m6);
def avg(xs: List[Int]) = xs.sum / xs.length
marks.groupBy(_.name).map { kv => Mark(kv._1, avg(kv._2.map(_.style_mark)), avg(kv._2.map(_.other_mark))) }
println(marks);
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激,
保罗
这里只是几点:
您可以使用模式匹配来避免元组附带的所有繁琐的_1,_2内容.
变量/参数名称中的下划线是Bad Thing™,它们已经在语言的其他地方使用得太多了
所以说:
更新:替换avg为avgOf,减少重复:)
//Needs two param lists so that inference will work properly
//when supplying the closure
def avgOf[T](xs:List[T])(f:(T)=>Int) = xs.map(f).sum / xs.length
marks.groupBy(_.name).map {
case (k,v) => new Mark(k, avgOf(v)(_.styleMark), avgOf(v)(_.otherMark))
}
Run Code Online (Sandbox Code Playgroud)
在现实世界中,我可能会通过pimp Traversable添加avgOf方法,因此您可以编写v.avgOf(_.styleMark),但这只会使这个示例复杂化.