高阶函数map, filter, reduce

2周前 36次点击 来自 Swift

原文链接:Swift Guide to Map Filter Reduce

map, filter, reduce是Swift提供的高阶函数,属于函数式编程的范畴。

相信只要有一定编程经验的开发者一眼就能知道它们的作用,高阶函数在一定程度上最大的作用就是方便替代集合对象的遍历操作。

map, filter, reduce在开发中属于高频使用,以下是一些使用的demo。

map

遍历一个集合对象,并将相同的操作应用于该对象的每一个元素。map函数返回了一个包含对该集合对象每一个元素进行相同操作、转换之后生成的新数值的数组。

实例:
对一个数组values做平方数操作

使用for循环

let values = [2.0, 4.0, 5.0, 7.0]
var squares: [Double] = []
for value in values {
   squares.append(value*value)
}

使用map:

let values = [2.0,4.0,5.0,7.0]
let squares = values.map({ (value: Double) -> Double in 
  return value * value
})
let squares = values.map { $0 * $0 }

函数式编程简洁写法(具体演化过程请参考:闭包):

let values = [2.0,4.0,5.0,7.0]
let squares = values.map { $0 * $0 }

根据上例可见,在一定程度上合理使用高阶函数可以让代码兼具简洁和可读性。

filter

遍历集合,将该集合中符合某些特定条件的元素组成新的数组,并返回该新数组。

let digits = [1, 4, 5, 10, 15]
let even = digits.filter { (number) -> Bool in return
   number % 2 == 0
}

更简洁的写法:

let digits = [1, 4, 10, 15]
let even = digits.filter { $0 % 2 == 0 }

reduce

将一个集合中的所有元素组合起来,生成一个新的值并返回该值,函数接收两个参数,一个初始值和一个组合闭包(combine closure)。

例如,计算Sum值。

let items = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let sum = items.reduce(0, +)

string拼接:

let codes = ["abc", "def", "ghi"]
let text = codes.reduce("New String is: ", +)
// "New String is: abcdefghi"

reduce函数的combine参数是一个闭包,所以我们也可以使用尾随闭包的语法形式来编写reduce函数,如下代码所示:

let name = ["alan", "brian", "charlie"]
let scv = name.reduce("===") { text, name in
    "\(text), \(name)"
}

// "===, alan, brian, charlie"

flatMap

用于将多个集合糅合成一个集合。

====
我们来看一个filterflatMap组合使用的例子,先将一个数组中的多个字数组扁平化(flat)为一个数组,然后再使用过滤(filter)筛选出数组中的偶数,如下:

let collections = [[5, 2, 7], [4, 8], [9, 1, 3]]
let onlyEven = collections.flatMap { intArray in
    intArray.filter { $0 % 2 == 0 }
    // result -- [2, 4, 8]
}

更简化的闭包语法版本:

let collections = [[5, 2, 7], [4, 8], [9, 1, 3]]
let onlyEven = collections.flatMap { $0.filter { $0 % 2 == 0 }}
// result -- [2, 4, 8]

====
再来一个flatMapmap组合使用,为一个包含多个整型子数组的数组内的所有整型元素计算平方值,并将计算后的平方值放入新数组返回:

let collections = [[5, 2, 7], [4, 8], [9, 1, 3]]
let allSquared = collections.flatMap { intArray in
    intArray.map { $0 * $0 }
}

// result -- [25, 4, 49, 16, 64, 81, 1, 9]

更简洁的闭包语法版本:

let collections = [[5, 2, 7], [4, 8], [9, 1, 3]]
let allSquared = collections.flatMap { $0.map { $0 * $0 }}

// result -- [25, 4, 49, 16, 64, 81, 1, 9]

====
再来一个flatMapreduce来计算一个数组中所有整型子数组的内的所有元素相加计算的和(sum):

let collections = [[5, 2, 7], [4, 8], [9, 1, 3]]
let sums = collections.flatMap { intArray in
    intArray.reduce(0, +)
}

更简洁的闭包语法版本:

let collections = [[5, 2, 7], [4, 8], [9, 1, 3]]
let sums = collections.flatMap { $0.reduce(0, +) }

链式语法

map, filter, reduce以及flatMap支持链式语法,例如计算集合中大于等于7的数字的和,可以先使用filter筛选,然后在使用reduce求和:

let marks = [4, 5, 8, 2, 9, 7]
let totalPass = marks.filter { $0 >= 7 }.reduce(0, +)
// result - 24
Card image cap
开发者雷

尘世间一个小小的开发者

技术文档 >> 系列应用 >>
热推应用

EntryS

学习Swift的入门教程
标签