Kotlin中函数式编程API(3)✔️三大基础函数

2019-06-13  本文已影响0人  狼性代码人
  • filter
  • map
  • reduce

  过滤映射聚合 是数据的三大基本操作,围绕这三大基础操作会有很多函数,但其中有三个函数是作为基础的函数:filtermapreduce

一、filter

  过滤操作使用filter函数,它可以对Collection集合、Map集合 或 数组 元素进行过滤,Collection 集合 和 数组 返回的是一个 List集合Map 集合返回的还是一个 Map 集合。

class Person(val name: String, val age: Int) {
    override fun toString(): String = "[$name, $age]"
}

val people = listOf(
    Person("Tony star", 3),
    Person("Lawrence Li", 3), Person("tom Chen", 3),
    Person("Alex", 3), Person("Xiao san", 3)
)

val peopleMap = mapOf(
    "a" to Person("Tony star", 3),
    "b" to Person("Lawrence Li", 3), "bf" to Person("tom Chen", 3),
    "af" to Person("Alex", 3), "sex" to Person("Xiao san", 3)
)

fun main(args: Array<String>?) {
    people.filter {
        it.name.startsWith("t", ignoreCase = true)
    }.forEach {
        println("{name=${it.name}, age=${it.age}}")
    }
    peopleMap.filter {
        it.key.startsWith("a") &&
                it.value.name.startsWith("a", ignoreCase = true)
    }.forEach { println("(${it.key}, ${it.value.toString()})") }
}
// 输出结果

2019-06-13 15:17:48.706 I: {name=Tony star, age=3}
2019-06-13 15:17:48.707 I: {name=tom Chen, age=3}
2019-06-13 15:17:48.710 I: (af, [Alex, 3])

  filter函数中的 Lambda 表达式返回布尔值,true的元素进入下一个函数,false的元素被过滤掉,表达式it.name.startsWith("t", ignoreCase = true)是判断集合元素的name属性是否为 t 字母开头,ignoreCase = true忽略大小写进行比较。

二、map

  映射操作使用 map 函数,它可以对 Collection 集合、Map 集合 或 数组 元素进行变换并 返回一个List 集合。

fun main(args: Array<String>?) {
    people.map { it.name }.forEach { println(it) }
    peopleMap.map { it.value }.filter { it.name.startsWith("T") }
        .forEach { println(it) }
}
// 输出结果

2019-06-13 15:38:40.567 I: Tony star
2019-06-13 15:38:40.567 I: Lawrence Li
2019-06-13 15:38:40.567 I: tom Chen
2019-06-13 15:38:40.567 I: Alex
2019-06-13 15:38:40.567 I: Xiao san
2019-06-13 15:38:40.573 I: [Tony star, 3]

  Map 函数对集合进行变换,it.name 是变换表达式,将计算的结果放到一个新的 List 集合中。

三、reduce

  聚合操作会将 Collection 集合 或 数组 中的数据聚合起来输出单个数据,聚合操作中最基础的是归纳函数 reducereduce 函数会将 集合数组 的元素按照指定的算法积累叠加起来,最后输出一个数据。

// reduce的kotlin源码

public inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S {
    val iterator = this.iterator()
    if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.")
    var accumulator: S = iterator.next()
    while (iterator.hasNext()) {
        accumulator = operation(accumulator, iterator.next())
    }
    return accumulator
}

  源码分析:1、从源码看 reduce 是迭代器的 Iterable 的扩展函数。2、从方法体第一行代码 val iterator = this.iterator() 分析凡是对象内含有 iterator() 函数并且返回值为 Iterator<T> 类型都可以调用 reduce 扩展函数。3、函数体内定义了局部变量 accumulator 存放返回值,初始值为迭代器的第一个存储值,当迭代器中存储值大于2个时,调用 operation 表达式运算,注意 operation 第一次调用时参数为 accumulator,即迭代器第一个存储值。

class Student(val name: String, val score: Int) {
    override fun toString(): String = "[$name, $score]"
}

val students = setOf(
    Student("Tony star", 64), Student("小三", 99),
    Student("Lawrence Li", 78), Student("tom Chen", 86),
    Student("Alex", 25), Student("小五", 95)
)

fun main(args: Array<String>?) {
    val total = students.map { it.score }.reduce { total, score -> total + score }
    println("total score is $total")
}
// 输出结果

2019-06-13 15:59:00.153 I: total score is 447

  调用 reduce 函数计算分数,其中 total 参数是上次积累的计算结果,score 为当前元素,total + score 表达式是进行累加。

上一篇 下一篇

猜你喜欢

热点阅读