Scala如何不使用不可变函数按电影体裁统计片长平均值?
实现思路
你现有代码存在两个问题:
- 没有将逗号分隔的多体裁拆分成单个体裁分别统计
- 仅存储了单条数据的片长,没有累计总时长和体裁出现次数,无法计算平均值
如果你要使用可变集合实现(不需要每次生成新的不可变Map),可以用scala.collection.mutable.HashMap来累计每个体裁的总时长和计数,示例代码如下:
import scala.collection.mutable // 假设你的list内的元素为样例类,结构参考如下 case class Movie(runtimeMinutes: Int, genres: String) val statMap = mutable.HashMap[String, (Int, Int)]() // key为体裁,value为(总时长, 出现次数) list.foreach { movie => // 拆分多体裁为单个体裁列表 val genres = movie.genres.split(",").map(_.trim) genres.foreach { genre => val (totalRuntime, count) = statMap.getOrElse(genre, (0, 0)) statMap.put(genre, (totalRuntime + movie.runtimeMinutes, count + 1)) } } // 计算每个体裁的平均片长 val avgRuntimeMap = statMap.mapValues { case (total, count) => total.toDouble / count }.toMap
用你给出的示例数据计算后,结果如下:
- Documentary: 1.0
- Short: 3.0
- Animation: 4.5
- Comedy: 4.0
- Romance: 4.0
如果你还是想用不可变的foldLeft实现,修正原有逻辑即可:
val avgRuntimeMap = list.foldLeft(Map[String, (Int, Int)]()) { case (acc, movie) => val genres = movie.genres.split(",").map(_.trim) // 遍历当前电影的所有体裁,逐个更新累加Map genres.foldLeft(acc) { case (innerAcc, genre) => val (total, count) = innerAcc.getOrElse(genre, (0, 0)) innerAcc + (genre -> (total + movie.runtimeMinutes, count + 1)) } }.mapValues { case (total, count) => total.toDouble / count }
内容的提问来源于stack exchange,提问作者Vivek Singh
相关产品推荐
相关产品推荐

