博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第十章 Scala 容器基础(十四):使用map把一个集合转化为另一个
阅读量:7235 次
发布时间:2019-06-29

本文共 2755 字,大约阅读时间需要 9 分钟。

hot3.png

Problem

    像上一节一样,你想把一个集合的每个元素通过某种算法变换后生成一个新的集合

Solution

    我们要调用集合的map方法,然后传给它一个函数、匿名函数或者方法来对每一个集合元素进行变换,而不是for/yield。下面这个例子中我们可以看到,我们把一组字符串的首字母变为大写:

scala> val helpers = Vector("adam", "kim", "melissa")helpers: scala.collection.immutable.Vector[String] = Vector(adam, kim, melissa)scala> helpers.map(e => e.capitalize)res26: scala.collection.immutable.Vector[String] = Vector(Adam, Kim, Melissa)scala> helpers.map(_.capitalize)res1: scala.collection.immutable.Vector[String] = Vector(Adam, Kim, Melissa)

    在下面这个例子中,我们把一个字符串集合转化成了一个整形集合:

scala> val names = Array("Fred", "Joe", "Jonathan")names: Array[String] = Array(Fred, Joe, Jonathan)scala> val lengths = names.map(_.length)lengths: Array[Int] = Array(4, 3, 8)

    同样地,map方法可以把一个集合转化为一个xml元素:

scala> val nieces = List("Aleka", "Christina", "Molly")nieces: List[String] = List(Aleka, Christina, Molly)scala> val elems = nieces.map(niece => 
  • {niece}
  • )elems: List[scala.xml.Elem] = List(
  • Aleka
  • Christina
  • Molly
  • )

        我们可以使用类似的方法,把一个集合转化为ul:

    scala> val ul = 
      {nieces.map(niece => 
    • {niece}
    • )}
    ul: scala.xml.Elem = 
    • Aleka
    • Christina
    • Molly

        被传入map方法的函数可以是任意复杂度的,当然函数的负责度这是根据你的需求来制定的。在Discussion中你会看到如何在map中使用一个多行匿名函数。当你的算法足够复杂,直到匿名函数无法满足你的需求的时候,你可以先定义一个函数,然后把这个函数传给map方法。

    scala> def plusOne(c: Char): Char = (c.toByte+1).toCharplusOne: (c: Char)Charscala> "HAL".map(plusOne)res2: String = IBM

        当你想定义一个能够传入map方法的函数的时候,这个函数必须只有一个和集合元素同类型的参数。在上面这个例子中,plusOne被定义为接受一个char,因为String世界上就是一个char的集合元素。函数的返回值可以是任何你想要的。实际上names.map(_.length)就是这么一个输入String,输出Int的函数。

        和for/yield结构不相同的地方是map方法可以形成一个方法调用链。也就是你可以在map方法后直接对map返回的集合进行其它操作活着把map加在一个返回集合的方法的后面。比如,你可以把一个字符串根据某中规则切分成一个字符串数组,然后再去掉字符串两边的空格。

    scala> val s = " eggs, milk, butter, Coco Puffs "s: String = " eggs, milk, butter, Coco Puffs "scala> val items = s.split(",").map(_.trim)items: Array[String] = Array(eggs, milk, butter, Coco Puffs)

    Discussion

        对于简单一点的情况来说,使用map和使用for/yield是一样:

    scala> val people = List("adam", "kim", "melissa")people: List[String] = List(adam, kim, melissa)scala> val caps1 = people.map(_.capitalize)caps1: List[String] = List(Adam, Kim, Melissa)scala> val caps2 = for (f <- people) yield f.capitalizecaps2: List[String] = List(Adam, Kim, Melissa)

        但是一旦当你添加guard(警卫)的时候,for/yield即可购就不再直接等于map方法调用了。拂过你尝试使用if字句在你的算法中,然后把这个函数传递给map方法,你会发现你得到了与你想象中不同的结果:

    scala> val fruits = List("apple", "banana", "lime", "orange", "raspberry")fruits: List[String] = List(apple, banana, lime, orange, raspberry)scala> fruits.map{ fruit => {     | if(fruit.length < 6) fruit.toUpperCase     | }}res5: List[Any] = List(APPLE, (), LIME, (), ())

        这样是不行的,但是你可以使用filter方法来对集合元素进行过滤,然后再执行map方法调用:

    scala> fruits.filter(_.length < 6).map(_.toUpperCase)res6: List[String] = List(APPLE, LIME)

    转载于:https://my.oschina.net/nenusoul/blog/657510

    你可能感兴趣的文章
    a.b.c.d.e.f.g这样的字段变成d.e.f.g的几种方法
    查看>>
    C++中关联容器和序列式容器在erase迭代器时的区别
    查看>>
    细谈围城---我的启示录
    查看>>
    字符串shuffle
    查看>>
    Nginx+PHP配置
    查看>>
    如何修改Xenserver网卡的offload
    查看>>
    Jmeter安装手记
    查看>>
    [视频教学]Maclean教你用Vbox在Enterprise Linux 5上安装Oracle 10gR2 RAC
    查看>>
    【Oracle Database 12c新特性】Online Statistics Gathering for Bulk-Load 针对批量数据加载的在线统计信息收集...
    查看>>
    windows下nginx 配置 tomcat 集群
    查看>>
    maven 常见故障处理
    查看>>
    Linux下安装mantis
    查看>>
    配置java环境变量时的一个陷阱(javapath)
    查看>>
    Python数据类型-类功能详解--【字符串】
    查看>>
    angular2 在header中带有继承的cookie
    查看>>
    maven规范:ssh框架整合
    查看>>
    KMP子串查找算法(二十六)
    查看>>
    硬盘SMART检测参数详解[转]
    查看>>
    异常解决java.io.IOException: invalid constant type: 15
    查看>>
    交换、比较
    查看>>