scala--函数组合子
程序员文章站
2022-03-11 19:02:29
...
package base.day03.functional.combinator
import scala.collection.GenTraversableOnce
/**
* @description 高阶函数map的应用,函数组合子
* 看看这边文章,相信你会对函数有更深的理解
* http://blog.csdn.net/bluishglc/article/details/45291533
* @author ZerlindaLi create at 2019/4/18 18:50
* @version 1.0.0
*/
object combinatorDriver {
def main(args: Array[String]): Unit = {
println("=============map===================")
/**
* map 对列表中的每个元素应用一个函数,返回应用后的元素所组成的列表
* map方法的定义如下:
* final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
*/
val numbers = List(1,2,3,4)
println(numbers.map((i:Int)=> i*2)) // =>List(2, 4, 6, 8)
// 传入一个函数(Scala编译器自动把我们的方法转换为函数)
def timesTwo(i:Int):Int = i * 2
def plusOne(i:Int):Int = i +1
println(numbers.map(timesTwo)) // =>List(2, 4, 6, 8)
println(numbers.map(plusOne)) // =>List(2, 3, 4, 5)
println("\n=============foreach==========")
/**
* foreach很像map,但没有返回值。foreach仅用于有副作用[side-effects]的函数。
* foreach方法定义如下,实现是对List做了一个while遍历:
* @inline final override def foreach[U](f: A => U)
*/
println(numbers.foreach((i:Int)=> i * 2)) // =>()
println(numbers) // => List(1, 2, 3, 4)
numbers.foreach((i:Int)=> print(i * 2 + " ")) // =>2 4 6 8
println("\n=============filter==========")
/**
* filter 移除任何对传入函数计算结果为false的元素,返回一个布尔值的函数通常被称为谓词函数[或判定函数]
* filter返回一个集合,它包含最终的元素
* def filter(p: A => Boolean): Repr = filterImpl(p, isFlipped = false)
*
* def filterNot(p: A => Boolean): Repr = filterImpl(p, isFlipped = true)
*
* private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
* val b = newBuilder
* for (x <- this)
* if (p(x) != isFlipped) b += x
*
* b.result
* }
*/
println(numbers.filter((i:Int) => i % 2 == 0)) // =>List(2, 4)
println(numbers) // =>List(1, 2, 3, 4)
def isEven(i:Int) : Boolean = i % 2 == 0
println(numbers.filter(isEven)) // =>List(2, 4)
println("\n=================zip===========")
/**
* zip 将两个列表的内容聚合到一个对偶列表中
* 获取两个集合的迭代器,同时遍历,都有值时组合成一个元组,放入新的集合
* def zip[A1 >: A, B, That](that: GenIterable[B])(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = {
* val b = bf(repr)
* val these = this.iterator
* val those = that.iterator
* while (these.hasNext && those.hasNext)
* b += ((these.next(), those.next()))
* b.result()
* }
*/
println(List(1,2,3).zip(List("a","b","c"))) // => List((1,a), (2,b), (3,c))
println("\n=================partition===========")
/**
* partition 将使用给定的谓词函数分割列表
*
*/
val numbers2 = List(1,2,3,4,5,6,7,8,9,10)
println(numbers2.partition(_ % 2 == 0)) // =>(List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))
println("\n==============find====================")
/**
* find 返回集合中第一个匹配谓词函数的元素
*
* def find(p: A => Boolean): Option[A] = {
* var these = this
* while (!these.isEmpty) {
* if (p(these.head)) return Some(these.head)
* these = these.tail
* }
* None
* }
*/
println(numbers2.find((i:Int) => i > 5)) // => Some(6)
println(numbers.find((i:Int) => i > 5)) // => None
println("\n==============drop & dropWhile====================")
/**
* drop 将删除前i个元素, 返回一个新的集合,原集合没有变化
*
* override def drop(n: Int): List[A] = {
* var these = this
* var count = n
* while (!these.isEmpty && count > 0) {
* these = these.tail
* count -= 1
* }
* these
* }
*
* dropWhile 将删除匹配谓词函数的第一个元素。例如,如果我们在numbers列表上使用dropWhile函数来去除奇数, 1将被丢弃(但3不会被丢弃,因为他被2“保护”了)。
* A为集合元素类型
* @inline final override def dropWhile(p: A => Boolean): List[A] = {
* @tailrec
* def loop(xs: List[A]): List[A] =
* if (xs.isEmpty || !p(xs.head)) xs
* else loop(xs.tail)
*
* loop(this)
* }
*/
println(numbers2.drop(5)) // => List(6, 7, 8, 9, 10)
println(numbers2) // => List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(numbers2.dropWhile(_ % 2 != 0)) // => List(2, 3, 4, 5, 6, 7, 8, 9, 10)
println("\n==============foldLeft====================")
/**
* [B]定义了一个泛型
* A表示集合元素的类型
* flodLeft函数将第一个参数依次与集合里面的元素从左往右依次左op操作。每次与元素操作后的值作为下一次op操作的一个参数的值
* override /*TraversableLike*/
* def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = {
* var acc = z
* var these = this
* while (!these.isEmpty) {
* acc = op(acc, these.head)
* these = these.tail
* }
* acc
* }
*/
println(numbers2.foldLeft("m")((m:String, n:Int)=>s"${m}${n}")) // => m12345678910
println("\n==============foldRight====================")
/**
* 与foldRight过程相反,foldRight是从右往左进行操作,"m"作为op的第二个参数值传入
* override def foldRight[B](z: B)(op: (A, B) => B): B =
* reverse.foldLeft(z)((right, left) => op(left, right))
*/
println(numbers2.foldRight("m")((m:Int, n:String)=>s"${m}${n}")) // => 12345678910m
println(numbers2.foldRight("m")((m:Int, n:String)=>s"${n}${m}")) // => m10987654321
println("\n==============flatten====================")
/**
* flatten将嵌套结构扁平化一个层级。
*
* asTraversable an implicit conversion which asserts that the element type of this $coll is a `GenTraversable`.
* 这是一个隐式参数。对于集合类型,都有一个隐式的遍历器,对于最外层集合的元素中含有非集合元素,则需要传入自定义的可遍历方法
* def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = {
* val b = genericBuilder[B]
* for (xs <- sequential)
* b ++= asTraversable(xs).seq
* b.result()
* }
*/
println(Set(List(1, 2), Map("a"->"A", "b"->"B"),Map("a"->"A", "b"->"B")).flatten) // => Set(1, 2, (a,A), (b,B))
println(List(List(1, 2), Map("a"->"A", "b"->"B"),Map("a"->"A", "b"->"B")).flatten) // => List(1, 2, (a,A), (b,B), (a,A), (b,B))
println("\n==============flatMap====================")
/**
* flatMap是一种常用的组合子,结合映射[mapping]和扁平化[flattening]。 flatMap需要一个处理嵌套列表的函数,然后将结果串连起来。
* 这个例子先调用map,然后调用flatten,这就是“组合子”的特征,也是这些函数的本质。
*/
val nestedNumbers = List(List(1,2), List(3,4), Map("a"->"A", "b"->"B"))
println(nestedNumbers.flatMap(x => x.map(_ + "0000"))) // => List(10000, 20000, 30000, 40000, (a,A)0000, (b,B)0000)
println("==================扩展函数组合子===================")
def ourMap(numbers2:List[Int], fn:Int=>Int):List[Int]={
numbers2.foldRight(List[Int]()){
(x:Int, xs:List[Int])=>
fn(x) :: xs
}
}
println(ourMap(numbers2, timesTwo(_))) // => List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
}
}
下一篇: SQLAlchemy查询
推荐阅读
-
js一组验证函数
-
php number_format() 函数通过千位分组来格式化数字的实现代码
-
一组PHP加密解密函数分享
-
python获取一组数据里最大值max函数用法实例
-
Excel MODE.MULT函数获取一组数值中出现频率最多的数据
-
python使用range函数计算一组数和的方法
-
在Word中插入函数公式对一组数据进行求和统计运算
-
php number_format() 函数通过千位分组来格式化数字的实现代码
-
oracle数据库相关练习一(基础、单行函数、组函数)
-
编写一个用户自定义函数,该函数有三个整数参数,函数的功能是:求解这三个整数的最大值,函数的返回值为三个参数的最大值。编写一个程序,从键盘输入N组数据,每组分别是任意5个整数,通过两次调用用户自定义函数