在Swift语言中使用MapFilterReduce对Array、Dictionary等集合类型(collection type)进行操作可能对一部分人来说还不是那么的习惯。对于没有接触过函数式编程的开发者来说,对集合类型中的数据进行处理的时候第一反应可能就是采用for in遍历。本文将介绍一些Swift中可以采用的新方法。

Map

Map函数会遍历集合类型并对其中的每一个元素进行同一种的操作。Map的返回值是一个所得结果的数组。例如:我们要对一个数组里面的数据进行平方操作,常见的代码如下:

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

上面的代码中,我们使用了常规的for in遍历操作对其中的元素进行了平方操作,然后将计算的结果追加到一个变量数组里面。虽然该部分的代码很好的完成了要求,但是在Swift中我们还有更简洁和安全的代码(上面的squaers是一个变量可能出现无意的数据修改)。下面来看看使用Map进行操作的代码:

let values: [Double]= [2.0,4.0,6.0,8.0]
let squares: [Double] = values.map{$0 * $0}

该段代码不仅更加简洁而且squares是一个不可变的常量。

上面代码中的map函数的闭包语法可能对于新手比较难以理解,该闭包中只有一行对集合中数据进行处理的代码并且最终返回了结果数组。为了大家更好的理解map的操作上面的代码可以改写为:

let values: [Double]= [2.0,4.0,6.0,8.0]
let squares: [Double] = values.map({
(value: Double)-> Double in
return value * value
})

上面这段改写的代码中闭包里面传入了一个Double类型的参数,并且返回了一个相同类型的处理结果。因为map只需要一个闭包最为参数,所以我们可以使用尾数闭包的特性去除(),而且闭包里面的代码也只有一行我们可以利用单表达式的隐式返回省略return

let squares: [Double] = values.map{value in value * value}

上面value也可以直接使用闭包的参数缩写功能给替换掉:

let squares: [Double] = values.map{$0 * $0}

map操作返回的结果数组中元素的类型并不要求与原来的元素类型一致,例如我们可以将一个常见的数字数组转为对应的单词数组:

let scores = [0,28,124]
let words = scores.map { NSNumberFormatter.localizedStringFromNumber($0, numberStyle: .SpellOutStyle) }
//["zero", "twenty-eight", "one hundred twenty-four"]

当然除了上面的Array,Set和Dictionary也能应用map操作。

Filter

Filter函数操作会对集合类型进行遍历并将其中的满足条件的元素作为结果数组中的元素进行返回。该函数里面只有一个作为条件判断的语句,闭包会遍历集合里面的元素并将满足条件的结果放在一起:

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

Reduce

Reduce函数操作会将集合类型里面的所有元素组合成一个新值并返回。reduce中的参数为两个:一个初始值、一个combine闭包。例如下面的代码将数组中的元素相加并且其中的初始值为10:

let items = [2.0,4.0,5.0,7.0]
let total = items.reduce(10.0,combine: +)
//28.0

除了上面的数字类型之外也可以对字符串进行处理:

let codes = ["Big","nerd","coding"]
let text = codes.reduce("", combine: +)
// "Bignerdcoding"

reduce中第二个参数是一个闭包,所有你可以使用尾随闭包来自我特定操作:

let codes = ["Big","nerd","coding"]
let text = codes.reduce("v2ex") {text, name in "\(text),\(name)"}
// "v2ex,Big,nerd,coding"

FlatMap

该函数会将那些多维集合类型转换为一维集合类型,实例如下:

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

另外对于可选类型的集合类型来说该函数还能将其中的空值移除掉:

let codes: [String?] = ["Big",nil,"nerd",nil,"coding"]
let values = codes.flatMap {$0}
// ["Big","nerd","coding"]

真正体现flatMap强大功能的地方是与上面一个函数进行组合操作:

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

上面的代码实现了将多维整形数组里面的偶数筛选出来并且组合成了一个一位数组。flatMap操作的参数是一个以[Int]数组作为参数的闭包。当然我们也可以使用隐含参数对其进行简写:

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

注意:上面简写中第一个和第二个$0表示collections中类似[5,2,7]的字数组,而第三个则表示子数组里面的每个整数

与其它操作进行组合的实例:

//与map操作的组合以及简写
let allSquared = collections.flatMap {
intArray in intArray.map { $0 * $0 }
} // [25, 4, 49, 16, 64, 81, 1, 9] let allSquared = collections.flatMap {
$0.map { $0 * $0 }
} //与reduce操作的组合以及对等的组合操作
let sums = collections.flatMap { $0.reduce(0, combine: +) } //对应的组合操作,两者结果是一样的
let sums = collections.map { $0.reduce(0, combine: +) }

链式组合

我们在上面已经看到了flatMap的闭包里面可以与另一操作的组合。我们还可以在闭包的外面对这些操作进行合理的组合来实现我们的目标。例如将数组中大于某个数字的所有数字进行求和操作:

let marks = [4,5,8,2,9,7]
let totalPass = marks.filter{$0 >= 7}.reduce(0,combine: +)
// 24

或者对某一个数组里面的数字进行平方操作然后在进行筛选:

let numbers = [20,17,35,4,12]
let evenSquares = numbers.map{$0 * $0}.filter{$0 % 2 == 0}
// [400, 16, 144]

总结

下次你要对集合类型的元素进行遍历并对其中的每个元素进行处理的时候,可以先检查一下是否可以直接使用上面的这些操作或者组合操作。

链接:

Swift函数编程之Map、Filter、Reduce

Swift函数编程之Map、Filter、Reduce的更多相关文章

  1. 高阶函数概念以及map/filter/reduce

    什么样的函数叫高阶函数:map(func, *iterables) --> map object 条件:1.函数接受函数作为参数 2.函数的返回值中包含函数 num_l = [1,2,3,4,5 ...

  2. python 内置函数 map filter reduce lambda

    map(函数名,可遍历迭代的对象) # 列组元素全加 10 # map(需要做什么的函数,遍历迭代对象)函数 map()遍历序列得到一个列表,列表的序号和个数和原来一样 l = [2,3,4,5,6, ...

  3. Swift map filter reduce 使用指南

    转载:https://useyourloaf.com/blog/swift-guide-to-map-filter-reduce/ Using map, filter or reduce to ope ...

  4. python常用函数进阶(2)之map,filter,reduce,zip

    Basic Python : Map, Filter, Reduce, Zip 1-Map() 1.1 Syntax # fun : a function applying to the iterab ...

  5. Python函数式编程之map()

    Python函数式编程之map() Python中map().filter().reduce()这三个都是应用于序列的内置函数. 格式: map(func, seq1[, seq2,…]) 第一个参数 ...

  6. 数组的高阶方法map filter reduce的使用

    数组中常用的高阶方法: foreach    map    filter    reduce    some    every 在这些方法中都是对数组中每一个元素进行遍历操作,只有foreach是没有 ...

  7. 如何在python3.3用 map filter reduce

    在3.3里,如果直接使用map(), filter(), reduce(), 会出现 >>> def f(x): return x % 2 != 0 and x % 3 != 0  ...

  8. Python map,filter,reduce函数

    # -*- coding:utf-8 -*- #定义一个自己的map函数list_list = [1,2,4,8,16] def my_map(func,iterable): my_list = [] ...

  9. 高阶函数map(),filter(),reduce()

    接受函数作为参数,或者把函数作为结果返回的函数是高阶函数,官方叫做 Higher-order functions. map()和filter()是内置函数.在python3中,reduce()已不再是 ...

随机推荐

  1. 开发者账号续期后,itunes停止付款了

    开发者账号过期后,没有及时续期,等再续期后,itunes停止付款到公司银行账户了.过了一个多月了还是没有收到itunes的付款.然后开始联系苹果客服和技术支持,他们都说只能通过itunes的“联系我们 ...

  2. mac 终端(terminal) 启动tomcat

    mac 终端启动tomcat: 找到你的tomcat安装的根目录:找到bin目录,在终端 cd 到这个bin中,输入sudo ./startup.sh (然后终端会提示你输入本机密码如果是在需要权限的 ...

  3. iOS多线程解析

    在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项.当然也会给出几种多线程的案例,在实际使用中感受它们的区别.还有一点需要说明的是,这篇文章将会使用 Swift 和 ...

  4. 在Mac上关于tomcat服务器的安装、配置、启动、部署web详细流程

    之前在Mac上通过安装mamp来搭建PHP环境服务器,但是对于java来说,目前还是没有找到类似mamp这样强大的软件来构建及管理java环境服务器,所以目前也是通过命令行来进行tomcat服务器的安 ...

  5. Java核心:类加载和JVM内存的分配

    类的加载: 指的是将class文件的二进制数据读入到运行时数据区(JVM在内存中划分的) 中,并在方法区内创建一个class对象. 类加载器: 负责加载编译后的class文件(字节码文件)到JVM(J ...

  6. redis使用笔记

    mysql---select * from table where xx;insert into table(name1,name2..) values(value1,value2);delete f ...

  7. u盘安装CENTOS后,启动missing operating system ,只能用U盘才能启动系统

    好久之前就想把家里闲置的那台老的不能再老的笔记本换成linux的,用来学习 从N久之前用光盘安装的时候发现光驱坏掉了之后就没有再装过,最近又想安装于是就试了U盘安装 U盘安装过程也很简单,只需要制作一 ...

  8. [20140829]spinlock导致cpu居高不下

    背景: 出现cpu高于常规的告警 排查: 1.开跟踪,没有发现cup特别高的查询 2.查看内核cpu使用量,看是否是sql server 端引起 3.查看负荷,是否负荷特别高这里使用 batch re ...

  9. PowerBI通过gateway连接多维数据库

    简介   Microsoft Power BI 是由微软推出的商业智能的专业分析工具,给用户提供简单且丰富的数据可视化及分析功能.个人非常喜欢,有免费版和Pro的付费版,今天主要是介绍下通过gatew ...

  10. 已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7};把数组a与数组b ,对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2];最后输出数组b的元素。

    int[]a={3,4,5,6,7}; int[]b={1,2,3,4,5,6,7}; int[] arry=new int[7]; System.out.print("数组b[]={&qu ...