------------------------------------------------------------------------- ************************************************************************* ------------------------------------------------------------------------- import scala.collection.mutable._ def indexes(a: Array[String], m: Map[String,Int]) = a.flatMap(m.get(_)) def indexes1(a: Array[String], m: Map[String,Int]) = a.map(m.get(_)) val am = Array("Tom", "Fred", "Harry") val m1 = Map("Dick" -> 4)
调用这俩个方法:
val inamm=indexes(am,m1) inamm.foreach(print(_)) println val inamm1=indexes1(am,m1) inamm1.foreach(print(_))
输出结果:
3
Some(3)NoneNone
-------------------------------------------------------------------------
*************************************************************************
-------------------------------------------------------------------------
很好奇为什么能过滤掉None,请教了scala中国群里的kerr、林晴、wxk、小星心等人,总结如下:
(1) m.get(_)的返回类型是Option[Int],这个好理解;源码中Option.class中有这样的隐式转换:
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList toList的定义如下:至此,对题目中的问题做了一个粗略的分析,由于是初学者,以后再慢慢清晰化。def toList: List[A] = if (isEmpty) List() else new ::(this.get, Nil)所以是转换为了List(2)或者List(),注意List(2)是单例List,即仅仅有一个元素。
-----------------------------------------
-----------------------------------------
(2)再看flatMap的源码(在Idea里面,按住Ctrl,然后鼠标点进去,即可看到调用的源码)
//这里是TraversableLike.class中def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { def builder = bf(repr) // extracted to keep method size under 35 bytes, so that it can be JIT-inlined val b = builder for (x <- this) b ++= f(x).seq b.result }注意代码实现部分主要与bf有关,在点进去看bf的实现:----------------------------------------- -----------------------------------------
trait CanBuildFrom[-From, -Elem, +To] { /** Creates a new builder on request of a collection. * @param from the collection requesting the builder to be created. * @return a builder for collections of type `To` with element type `Elem`. * The collections framework usually arranges things so * that the created builder will build the same kind of collection * as `from`. */ def apply(from: From): Builder[Elem, To]显然是调用了apply(from:From),点进去Builder:----------------------------------------- -----------------------------------------
import generic._ /** The base trait of all builders. * A builder lets one construct a collection incrementally, by adding * elements to the builder with `+=` and then converting to the required * collection type with `result`. * * @tparam Elem the type of elements that get added to the builder. * @tparam To the type of collection that it produced. * * @since 2.8 */ trait Builder[-Elem, +To] extends Growable[Elem] { /** Adds a single element to the builder. * @param elem the element to be added. * @return the builder itself. */从英文部分可得到下面的naive interpretation----------------------------------------- -----------------------------------------
implicit bf: CanBuildFrom[Repr, B, That],它这个是先让this.asInstanceOf(Repr),然后逐个添加元素B,最后返回结果That。
即它是要求输入数据是Repr,添加这个集合中的数据是B,这个集合的result()方法返回的是That类型.----------------------------------------- -----------------------------------------
(3) 正是bf++=f(x).seq,f(x)是List,List中++是可以过滤掉List()的。
有问题请及时留言或者发送邮件到zhanghao_study@163.com.