变换函数

map

  • map变换函数会遍历接收者集合,让变换器函数作用于集合里的各个函数,返回结果是包含已修改的集合,会作为链上下一个函数的输入
val fruits: List<String> = listOf("Apple", "Banana", "Orange", "Lemon")
val ownFruits: List<String> =
fruits.map { fruit -> "I have $fruit" }
.map { owner -> "$owner,and I love it" }
println(fruits)
println(ownFruits)

//输出
[Apple, Banana, Orange, Lemon]
[I have Apple,and I love it, I have Banana,and I love it, I have Orange,and I love it, I have Lemon,and I love it]

可以看到,原始集合并没有修改,map变换函数和你定义的变换器函数做完事情后,返回的是一个新集合,这样,变量就不用变来变去了。

  • 事实上,函数式编程范式支持的设计理念就是不可变数据的副本在链上的函数间传递

map返回的集合中的元素个数和输入集合必须一样,不过,返回的新集合里的元素可以是不同类型的.

val lengthList = fruits.map {
it.length
}
println(lengthList)
//结果
[5, 6, 6, 5]

flatMap

  • flatMap函数操作一个集合的集合,将其中多个集合的元素合并后返回一个包含所有元素的单一集合
val flatMap = listOf(listOf(1, 2, 3), listOf(4, 6, 5)).flatMap { it }
println(flatMap)
//结果
[1, 2, 3, 4, 6, 5]

过滤函数

​ 过滤是函数式编程的第二大函数,过滤函数接收一个predicate函数,用它按给定条件检查接收者集合里的元素并给出true或false的判定。如果predicate函数返回true,受检元素就会添加到过滤函数返回的新集合里,如果predicate函数返回false,那么受检元素就被移出新集合

filter

过滤集合中含有“J”的元素

val result = listOf("Jack", "Lee", "Jim", "Jimy", "Tomas").filter { 		              it.contains("J") }
println(result)
//结果
[Jack, Jim, Jimy]
val items = listOf(
listOf("red apple", "green apple", "blue apple"),
listOf("red fish", "blue fish"),
listOf("yellow banana", "teal banana")
)
val redItems = items.flatMap {
it.filter { item ->
item.contains("red")
}
}
println(redItems)
//结果
[red apple, red fish]

找素数

    val numbers = listOf(7,4,8,4,3,22,16,17,23,18,11,5,9,121,131)
val primes = numbers.filter { number ->
(2 until number).map { number % it }.none { it == 0 }
}
println(primes)
//结果
[7, 3, 17, 23, 11, 5, 131]

合并

zip

zip合并函数用来合并两个集合,返回一个包含键值对的新集合。

val employees = listOf("Jack", "Jason", "Tommy","Jimmy")
val shirtSize = listOf("large", "x-large", "medium")
val employeeMap = (employees zip shirtSize).toMap()
val jack = employeeMap["Jack"]
println(jack)
println(employeeMap)
//结果
large
{Jack=large, Jason=x-large, Tommy=medium}

通过对zip函数的定义

public infix fun <T, R> Iterable<T>.zip(other: Iterable<R>): List<Pair<T, R>> {
return zip(other) { t1, t2 -> t1 to t2 }
}

可以看到,结果返回的是一个List集合,里面的值是键值对

为了方便使用,我们可以自定义一个zipMap函数,直接将结果返回为Map

public infix fun <T, R> Iterable<T>.zipMap(other: Iterable<R>): Map<T, R> {
return (this zip other).toMap()
}

用法也很简单:

val map = employees zipMap shirtSize
println(map)
//结果
{Jack=large, Jason=x-large, Tommy=medium}

fold

另一个可以用来合并至的合并类函数式fold,这个合并函数接收一个初始累加器值,随后会根据匿名的结果更新

//将每个元素值乘以3后累加起来
val foldValue = listOf(1, 2, 3, 4).fold(0) { accumulator, number ->
println("Accumulated value: $accumulator,$number")
accumulator + number * 3
}
println("Final value: $foldValue")
}

//结果
Accumulated value: 0,1
Accumulated value: 3,2
Accumulated value: 9,3
Accumulated value: 18,4
Final value: 30