Twitter的Scala School上面对map()函数介绍如下:
Evaluates a function over each element in the list, returning a list with the same number of elements.
1 2 3 4 |
scala> val numbers = List(1, 2, 3, 4) numbers: List[Int] = List(1, 2, 3, 4) scala> numbers.map((i: Int) => i * 2) res0: List[Int] = List(2, 4, 6, 8) |
Scala官网上面的介绍:
1 2 3 |
def map[B](f: (A) ⇒ B): Traversable[B] [use case] Builds a new collection by applying a function to all elements of this traversable collection. |
Twitter的解释是对一个list的每个element作用一个function,并返回数量相同的list。Scala官网则只说对一个collection的每个元素作用一个function,并返回一个新的collection。
对于只认真看过Scala School的我而言,map的作用就是对一个collection的每个元素作用一个function,并返回一个相同大小的collection。[哭笑不得]
于是就出现了一个让我找了大半个下午的bug:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def getSumResult(stats: Map[String, String]) = { stats .filter(item => !FS_SET.contains(item._1)) .map { item => val (_, value) = item val json = parse(value) val _total = (json \ "total").extractOrElse(0) val _success = (json \ "success").extractOrElse(0) (_total, _success) }.reduce {(left, right) => (left._1 + right._1, left._2 + right._2) } } |
目的是对一个Map[String, String]对象做统计值,然而没有想到的是Map[String, String]对象通过map()函数得到的还是一个Map[String, String]对象。为什么这样?因为我的返回值是一个Tuple,而通过Tuple是构造Map的方法之一。于是我想象中的List[(Int, Int)]没有出现,而是出现了一个Map[Int, Int]。
于是坑爹的事情来了,通过map()函数作用以后返回的是Map[Int, Int],代表key相同的记录只能存在一个,于是_total相同的记录最终只能有一个,所以导致统计的结果错误。
经验教训:多看官网多思考,不要异想天开一厢情愿
company website гидра зеркало