• Scala012--Scala中的常用集合函数及操作Ⅲ


    在之前的两篇中我已经将Scala中常用的集合和函数认识了大半,现在就只剩下了最后几个函数。

    目录

    一,grouped函数

    1,按照元素分组(两两分组)

    2,两两分组并输出结果

    二,groupBy函数

    1,按照奇偶进行分组

    2, 按照单词首字母进行聚合

    3,元组分组

    4,按照成绩分组

    三,mapValues函数

    1,对map中嵌套的数组进行求和

    2,按照单词把元素分到一组,并获取每一组中元素个数

    四,diff,union,intersect函数

    1,diff函数

    2,union函数

    3,intersect函数


     

    一,grouped函数

    grouped函数返回值为iterator迭代器,普通的打印是看不到具体的结果的,但是我们可以将集合序列转换成列表或者是数组,之后再通过foreach函数或者是for函数遍历打印出来即可。

    源码中的grouped函数:
    def grouped(size: Int): Iterator[Repr] =
      for (xs <- iterator grouped size) yield {
        val b = newBuilder
        b ++= xs
        b.result()
      }

    现在我去使用具体的案例来对这个函数进一步了解。

    1,按照元素分组(两两分组)

    Array(1,2,3,4,5,6,7)

    OUT===>

    List(1, 2)
    List(3, 4)
    List(5, 6)
    List(7)

    1. scala> val arrDemo1=Array(1,2,3,4,5,6,7)
    2. arrDemo1: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7)
    3. scala> arrDemo1.grouped(2) // 对数组中的元素进行两两分组
    4. res19: Iterator[Array[Int]] =

     如上,我发现返回的类型确实就是迭代器,这个时候并不能够看到分组之后的结果,,但是可以使用toList或者是toBuffer函数将迭代器转换成列表或者是数组:

    scala> res19.toList  // 将之前处理后的结果转换成列表集合序列

     但是上面的结果并不是我想要的效果:

    List(1, 2)
    List(3, 4)
    List(5, 6)
    List(7)

    这个时候就可以使用foreach函数,在遍历列表中的数组时,将数组转换成列表再输出即可:

    scala> res20.foreach(arr=>println(arr.toList))  // 在遍历列表时,将列表中嵌套的数组转换成列表类型

     如上就实现了需求。

    2,两两分组并输出结果

    Array(1,2,3,4,5,6,7,8,9)

    OUT===>

    2
    1
    4
    3
    6
    5
    8
    7
    9

     从上面的输出结果可以发现不仅需要两两分组,还需要将分组后的数组进行反转,并遍历输出。

    1. scala> val arrDemo=Array(1,2,3,4,5,6,7,8,9)
    2. arrDemo: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
    3. scala> arrDemo.grouped(2) // 对数组中的元素进行两两组
    4. res24: Iterator[Array[Int]] =
    5. scala> res24.toBuffer // 查看分组后的结果
    6. res25: scala.collection.mutable.Buffer[Array[Int]] = ArrayBuffer(Array(1, 2), Array(3, 4), Array(5, 6), Array(7, 8), Array(9))
    7. scala> res25.map(f=>f.reverse) // 使用map函数,将数组中的每一个数组都进行反转
    8. res26: scala.collection.mutable.Buffer[Array[Int]] = ArrayBuffer(Array(2, 1), Array(4, 3), Array(6, 5), Array(8, 7), Array(9))
    9. scala> res26.flatten // 对结果进行扁平化操作
    10. res27: scala.collection.mutable.Buffer[Int] = ArrayBuffer(2, 1, 4, 3, 6, 5, 8, 7, 9)
    11. scala> res27.foreach(println) // 遍历数组
    12. 2
    13. 1
    14. 4
    15. 3
    16. 6
    17. 5
    18. 8
    19. 7
    20. 9

    二,groupBy函数

    groupBy函数相比于group函数,groupBy函数能够指定分组的依据是什么,而不是只能够进行两两分组,三三分组这些单调的操作。需要注意的是groupBy函数返回值为Map键值对类型。

    groupBy函数的源码:
    def groupBy[K](f: A => K): immutable.Map[K, Repr] = {
      val m = mutable.Map.empty[K, Builder[A, Repr]]
      for (elem <- this) {
        val key = f(elem)
        val bldr = m.getOrElseUpdate(key, newBuilder)
        bldr += elem
      }

    接下来使用具体的代码和习题来更进一步了解该函数: 

    1,按照奇偶进行分组

    Array(1,2,3,4,5,6,7,8)

    OUT===>

    Map(odd -> Array(1, 3, 5, 7), even -> Array(2, 4, 6, 8))

    首先先定义一个数组: 

    scala> val arrDemo1=Array(1,2,3,4,5,6,7,8)  

    之后就可以调用groupBy函数并向里面写入表达式: 

    1. scala> arrDemo1.groupBy(
    2. | f => if (f %2==0) "even" else "odd") // 如果为偶数则分到even组,否则为odd组

     如上,得到结果。

    2, 按照单词首字母进行聚合

    Array("hello","hi","haha","word","wangwu","tt","tom","a","aa","b")

    OUT===>

    Map(h -> Array(hello, hi, haha), w -> Array(word, wangwu), t -> Array(tt, tom)) Array(1, 3, 5, 7), true -> Array(2, 4, 6, 8))

     字符串中获取首字母的函数为substring(0,1),之后将这个作为依据传入groupBy函数中即可:

    1. scala> val arr_str=Array("hello","hi","haha","word","wangwu","tt","tom","a","aa","b")
    2. arr_str: Array[String] = Array(hello, hi, haha, word, wangwu, tt, tom, a, aa, b)
    3. scala> arr_str.groupBy(f=>f.substring(0,1))
    4. res31: scala.collection.immutable.Map[String,Array[String]] = Map(t -> Array(tt, tom), a -> Array(a, aa), b -> Array(b), h -> Array(hello, hi, haha), w -> Array(word, wangwu))

     如上,得到结果。

    3,元组分组

    List(("a", 10), ("b", 2), ("a", 3))

    OUT===>

    Map(a -> List((a,10), (a,3)), b -> List((b,2)))

    如上,可以发现,分组的依据是对偶元组中的字母,也就是说我只需要获取到对偶元组中的字母即可:

    1. scala> val list_tup2=List(("a", 10), ("b", 2), ("a", 3))
    2. list_tup2: List[(String, Int)] = List((a,10), (b,2), (a,3))
    3. scala> list_tup2.groupBy(f=>f._1)
    4. res32: scala.collection.immutable.Map[String,List[(String, Int)]] = Map(b -> List((b,2)), a -> List((a,10), (a,3)))

     如上,得到结果。

    4,按照成绩分组

    Array(("zhangsan",90),("lisi",80),("wangwu",49),("xiaoliu",28))

    OUT===>

     Map(true -> Array((zhangsan,90), (lisi,80)), false -> Array((wangwu,49), (xiaoliu,28)))

     观察输出的结果可知,成绩分组的依据是按照成绩是否及格(及格表示大于60),因此,在获取到元组中的成绩之后,再将其与60进行比较即可(<60):

    1. scala> val arr_tup2=Array(("zhangsan",90),("lisi",80),("wangwu",49),("xiaoliu",28))
    2. arr_tup2: Array[(String, Int)] = Array((zhangsan,90), (lisi,80), (wangwu,49), (xiaoliu,28))
    3. scala> arr_tup2.groupBy(f=>if (f._2<60) true else false)
    4. res34: scala.collection.immutable.Map[Boolean,Array[(String, Int)]] = Map(false -> Array((zhangsan,90), (lisi,80)), true -> Array((wangwu,49), (xiaoliu,28)))

    如上,得到结果。

    三,mapValues函数

    mapValues的源码:
    override def mapValues[C](f: B => C): Map[A, C] = new MappedValues(f) with DefaultMap[A, C]
    

    mapValues函数其实有点像之前学map数据结构时,使用的keys和values函数的结合体。它能够获取到map集合序列中的键值对,并且能够通过键对键直接进行运算,返回的结果依旧时map集合序列,还是键值对的形式。接下来,我通过以下几道题对该函数的具体使用进一步加深理解。

    1,对map中嵌套的数组进行求和

    Map("a" -> List(1, 2, 3), "b" -> List(4, 5, 6))

    OUT===>

    Map(a -> 6, b -> 15)

     观察上式可得两点:①返回的结果为键值对;②对map集合序列中的每一个列表都进行了求和。

     接下来我们就可以知道使用的一定时mapValues函数(因为在map集合序列中只有该函数的返回值为键值对),之后使用该函数之后,传入的参数代表每一个key,之后由key得到每一个value(在这个例子中为每一个列表集合序列)。之后就可以开始敲代码:

    1. scala> val map_list=Map("a" -> List(1, 2, 3), "b" -> List(4, 5, 6))
    2. map_list: scala.collection.immutable.Map[String,List[Int]] = Map(a -> List(1, 2, 3), b -> List(4, 5, 6))
    3. scala> map_list.mapValues(f=>f.sum)
    4. res35: scala.collection.immutable.Map[String,Int] = Map(a -> 6, b -> 15)

    2,按照单词把元素分到一组,并获取每一组中元素个数

     List(("a", 10), ("b", 2), ("a", 3))

    OUT===>

     Map(b -> 1, a -> 2)

     我从输出可知:先使用groupBy函数按照元组中的第一个元素进行分组,之后再使用mapValues函数得到values有多少个:

    1. scala> list_tup2.groupBy(f=>f._1) // 根据元组中的第一个元素分组
    2. res37: scala.collection.immutable.Map[String,List[(String, Int)]] = Map(b -> List((b,2)), a -> List((a,10), (a,3)))
    3. scala> res37.mapValues(f=>f.size)
    4. res38: scala.collection.immutable.Map[String,Int] = Map(b -> 1, a -> 2)

    四,diff,union,intersect函数

    1,diff函数

    diff函数的源码:
    def diff[B >: A](that: GenSeq[B]): Repr = {
      val occ = occCounts(that.seq)
      val b = newBuilder
      for (x <- this) {
        val ox = occ(x)  // Avoid multiple map lookups
        if (ox == 0) b += x
        else occ(x) = ox - 1
      }
      b.result()
    }

    diff函数主要是用于两个集合序列中的比较。例如:集合1.diff(集合2),如果集合1中有集合2中没有的元素,那么返回值就会是集合2中没有的元素。接下来我们使用代码来一探究竟。

    需要用到的两个集合序列:

    1. scala> arrDemo
    2. res41: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
    3. scala> arrDemo1
    4. res42: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8)

     之后让arrDemo集合去调用diff函数并于arrDemo2集合进行比较,那么结果就会是(9):

    scala> arrDemo.diff(arrDemo1)

     如果是让arrDemo集合去调用diff函数并于arrDemo2集合进行比较,那么结果就会是空:

    因为arrDemo1中的元素arrDemo中都有,所以与arrDemo之间就没有任何元素的差异。

    2,union函数

    union函数源码:
    override def union[B >: A, That](that: GenSeq[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
      this ++ that

    union函数就像是MySQL中的外连接一样,主要是用于合并两个集合序列的,不管是不是重复都会将所有的元素添加到一起,并返回一个型的集合序列:

    scala> arrDemo.union(arrDemo1)

    3,intersect函数

    intersect函数源码:
    def intersect[B >: A](that: GenSeq[B]): Repr = {
      val occ = occCounts(that.seq)
      val b = newBuilder
      for (x <- this) {
        val ox = occ(x)  // Avoid multiple map lookups
        if (ox > 0) {
          b += x
          occ(x) = ox - 1
        }
      }
      b.result()
    }

    intersect:横断;相交;交叉;横穿;贯穿

    该函数主要是取两个集合的交集,即获取相同的元素,并返回一个新的集合序列:

    scala> arrDemo.intersect(arrDemo1)

     以上就是集合序列中常用的所有函数,如果有问题请在评论区留言。

  • 相关阅读:
    【温故而知新-02】C++函数参数传递
    手机端预览pdf,兼容安卓iOS和pc端
    [mit6.1810] Lab system calls
    虚拟现实(VR)的应用场景
    Mybatis-plus中更新date类型数据遇到的坑
    删除的通话记录也能找回!如何iPhone很早以前的通话记录
    HCIP---IS-IS协议
    多环境的axios配置和简易版配置
    Linux命令行技巧
    CSS基础入门02
  • 原文地址:https://blog.csdn.net/weixin_53046747/article/details/128087837