zoukankan      html  css  js  c++  java
  • 高阶函数

    1. map/flatMap:对数据集中的每条数据处理,有返回值
    2. sorted/sortedBy/sortWith:对数据集中的数据按照指定的方式进行排序
    3. groupBy:对数据集中的的数据按照某种方式进行分组
    4. reduce/fold:对数据集中的数据进行合并
    5. filter/filterNot:对数据集中的数据进行过滤
    6. foreach:对数据集中的每条数据处理,没有返回值

    map和flatMap

    map

        //在高阶函数里面下面的写法就更加的优化,可以获取各个值
          RDD.map(item=>{
            val Array(name, age, sex, phone) = item.split(",")
            name
          })
    
            val list = List(1, 2, 7, 8, 3, 4, 9, 10, 6, 5)
          /**
            * def map(f: A => B)
            * map的参数是一个函数。f: A => B
            * A -> 表示的是列表List中数据类型,此处是Int类型
            * 此处 B属于泛型,不是Unit类型
            * 作用:对集合中每一个元素进行操作,将每个元素传递到指定的函数f中,进行操作,并且有返回值
            */
          val mapList: List[Double] = list.map(item => item * 2.0)
          list.map(item => {
            println(s"item = $item, transform = ${item * 2.0}")
            item * 2.0
          })

     flatMap

       /**
          * flatMap() -> f: A => Traversable[B]
          * 对List中每个元素进行操作,将每个元素传入到函数f中,进行操作,返回Traversable
          * Traversable:是可遍历对象,可以认为就是一个集合
          * 然后将每个Traversable中的元素映射到新的List集合(RDD)中
          */
        val flatMapList= list.flatMap(item => {
          val range: Inclusive = 0 to item
                println(s"item = $item, range = ${range.mkString("|")}")
                range.mkString("|").split("|")
        }).foreach(println)

    Map和flatMap的区别

    //     map和flatmap区别:map不会增加RDD的count,flatMap会增加RDD的count
    //     flatmap的f函数的返回值是Traversable,然后将Traversable中的每个元素映射到新的RDD(list)中,会增加RDD的count
    //     map的f函数的返回值可以是不为Unit的任意的数据类型
        val lineList = List("hadoop,spark,hive,spark,hadoop,spark", "spark,spark")
        lineList.map(line => line.split(",").toList.mkString(" ")).foreach(println)
        lineList.flatMap(line => line.split(",")).foreach(println)

    sorted/sortedBy/sortWith

    1. sorted/sortBy/sortWith:都是对集合中的元素进行排序
    2. 只有soreBy是RDD的函数,使用的时候execute的数目只能设置为一个
        val li = List(7, 8, 3, 4, 9)
        val list: RDD[Int] = sc.parallelize(li)
    //  sorted:默认的情况下,按照数据的自然方式进行升序排序
          li.sorted.foreach(item => println(item))
    //  def sortBy[B](f: A => B):按照函数特定的方式排序
          list.sortBy(item => - item).foreach(item => println(item))
    //  def sortWith(lt: (A, A) => Boolean):按照比较之后结果为true的方式排序
         li.sortWith((x1, x2) => {
           println(s"x1 = $x1, x2 = $x2")
           x1 > x2
         }).foreach(item => println(item))

    groupBy

      /**
          *   def groupBy(f: A => K)
          *   说明:集合中每个元素应用到函数f中,返回值k就是分组的类别
          */
        val list = List(7, 8, 3, 4, 9)
        val groupMap: Map[String, List[Int]] = list.groupBy(item => if(item % 2 ==0) "偶数" else "奇数")
        
        // 列表中存在数据类型二元组
        val tupleList = List(("spark", 34), ("scala", 12), ("spark", 10), ("spark", 1), ("hive", 1)
        val tupleGroupMap: Map[String, List[(String, Int)]] = tupleList.groupBy(item => item._1)
        tupleGroupMap.map(t2 => {
          val word: String = t2._1
          val list: List[(String, Int)] = t2._2
          val  count = list.map(item => item._2).sum
          (word, count)
        })

    reduce/fold

    1. left:有三层含义:
      1. f函数的左边的参数为中间临时变量
      2. 集合从左边开始聚合
      3. 集合左边的第一个元素为中间临时变量的初始值
    2. reduce和reduceLeft的区别:
      1. reduceLeft中间临时变量的数据类型是集合中传入的数据类型的父集(reduceLeft的函数参数的返回值向上转型)   def reduceLeft[B >: A](f: (B, A) => B)
      2. reduce:中间临时变量的数据类型和传入数据中数据类型相同    def reduce(op: (A1, A1) => A1)
    3. fold和foldLeft的区别:
      1. foldLeft:中间临时变量的类型 是任意类型def foldLeft[B](z: B)(f: (B, A) => B)
      2. fold:初始赋值的数据类型和传入数据中数据类型相同def fold(z: A1)(op: (A1, A1) => A1)
    4. reduceLeft和foldLeft的区别:
      1. reduceLeft:中间变量的初始值只能是集合中左边的第一个元素,数据类型为集合中元素的父集   def reduceLeft[B >: A](f: (B, A) => B)
      2. foldLeft:中间变量的初始值是自己选择的任意类型 def foldLeft[B](z: B)(f: (B, A) => B)

    reduce

        /**
          * def reduce(op: (A1, A1) => A1): A1 =reduceLeft(op)
          *   - reduce函数中参数的类型是一个函数,并且是两个参数的:
          *     op 函数的要求如下;
          *       第一点:参数类型和返回值的类型是一致的
          *       第二点:有两个参数,其中
          *         第一个参数为“聚合”的中间临时变量,初始值为第一个元素的值
          *         第二个参数是集合中除去第一个元素以外的每个元素的值
          */
        list.reduce((x1, x2) => {
          println(s"x1 = $x1, x2 = $x2")
          x1 + x2
        })

    reduceLeft

       /**
          *   def reduceLeft[B >: A](f: (B, A) => B): B
          *   - reduceLeft函数中参数的类型是一个函数,并且是两个参数的:
          *     op 函数的要求如下;
          *       第一点:中间临时变量的参数类型B是集合中传入参数类型A的父集,返回值类型是中间临时变量类型B
          *       第二点:有两个参数,其中
          *         第一个参数B为“聚合”的中间临时变量,初始值是从左边开始选的,reduce底层就是调用reduceLeft
          *         第二个参数A是集合中除去第一个元素以外的每个元素的值
          */
        list.reduceLeft((tmp, item) => {
          println(s"tmp = $tmp, x2 = $item")
          tmp + item
        })

    reduceRight

     /**
          *    def reduceRight[B >: A](op: (A, B) => B): B
          *   - reduceRight函数中参数的类型是一个函数,并且是两个参数的:
          *     op 函数的要求如下;
          *       第一点:中间临时变量的参数类型B是集合中传入参数类型A的父集,返回值类型是中间临时变量类型B
          *       第二点:有两个参数,其中
          *         第一个参数B为“聚合”的中间临时变量,初始值是从右边开始选的
          *         第二个参数A是集合中除去第一个元素以外的每个元素的值
          */
        list.reduceRight((item, tmp) => {
          println(s"tmp = $tmp, x2 = $item")
          tmp + item
        })

    fold

       /**
          * def fold(z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)
          * 参数说明:
          *   -a. 第一个参数:z
          *     表明的是Zero(初始化):中间临时变量的初始化值
          *   -b. 第二个参数:op: (A1, A1) => A1
          *     A1表示的是中间临时变量 类型
          *     A2 表示的是 集合个每个元素;类型
          *   -c. 中间临时变量。临时变量的初始值,返回值和集合中的元素都相同
          */
        val list = List(1, 2, 7, 8, 3, 4, 9, 10, 6, 5)
        // 求和,此处使用fold函数大材小用
        list.fold(0)((tmp, item) => {
          println(s"tmp = $tmp, item = $item")
          tmp + item
        })

    foldLeft

       /**
          *  def foldLeft[B](z: B)(f: (B, A) => B): B
          *  参数说明:
          *   -a. 第一个参数:z
          *     表明的是Zero(初始化):中间临时变量的初始化值
          *   -b. 第二个参数:(f: (B, A) => B
          *     B表示的是中间临时变量 类型
          *     A表示的是 集合个每个元素类型
          *   -c. 中间临时变量不需要和集合中的元素的值相同,可以是自己定义的任何数据类型
          */
        val lst = List(11, 22, 11, 11, 22, 99, 100)
        // TODO: 使用foldLeft/foldRight函数对集合中数据进行去重
        import scala.collection.mutable
        lst.foldLeft(mutable.Set[Int]())((set, item) => {
          println(s"set = $set, item = $item")
          set += item
        })

    foldRight

     /**
          *  foldRight[B](z: B)(op: (A, B) => B): B
          *  参数说明:
          *   -a. 第一个参数:z
          *     表明的是Zero(初始化):中间临时变量的初始化值
          *   -b. 第二个参数:(op: (A, B) => B
          *     B表示的是中间临时变量 类型
          *     A表示的是 集合个每个元素类型
          *   -c. 中间临时变量不需要和集合中的元素的值相同,可以是自己定义的任何数据类型
          */
        lst.foldRight(mutable.Set[Int]())((item, set) => {
          println(s"set = $set, item = $item")
          set += item
        })

    filter/filterNot

        /**
          * def filter(p: A => Boolean):
          *   将集合中的每一个元素传递到函数p中,返回值是Boolean类型
          *   filter的结果是函数p的返回值是true的元素组成的新的集合
          */
        list.filter(item => item % 2 != 0).foreach(println)
        /**
          * def filterNot(p: A => Boolean):
          *   将集合中的每一个元素传递到函数p中,返回值是Boolean类型
          *   filterNot的结果是函数p的返回值是false的元素组成的新的集合
          */
        list.filterNot(item => item % 2 == 0).foreach(println)

    foreach

    // def foreach(f: T => Unit):针对集合中每个元素进行操作,没有返回值
      list.foreach(item =>item.toString)
      list.foreach(item => println(s"item = $item, transform = ${item * 2.0}"))
  • 相关阅读:
    聊聊WS-Federation
    用双十一的故事串起碎片的网络协议(上)
    责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
    最小化局部边际的合并聚类算法(中篇)
    最小化局部边际的合并聚类算法(上篇)
    UVaLive 7371 Triangle (水题,判矩形)
    UVaLive 7372 Excellence (水题,贪心)
    POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
    UVa 1252 Twenty Questions (状压DP+记忆化搜索)
    UVa 10817 Headmaster's Headache (状压DP+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/WeiKing/p/11543239.html
Copyright © 2011-2022 走看看