Swift函数编程之Map、Filter、Reduce

在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

时间: 2024-10-14 11:19:31

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

Swift详解之五-----------map,filter,reduce

map,filter,reduce 注:本文为作者自己总结,过于基础的就不再赘述 ,都是亲自测试的结果.如有错误或者遗漏的地方,欢迎指正,一起学习. 关于Swift 中String .数组 .字典的基本用法这里就不再赘述了,这些都很简单 不会的 在用得时候baidu下就行了.这里主要看下这几个高阶函数 map map方法,其获取一个闭包表达式作为其唯一参数. 数组中的每一个元素调用一次该闭包函数,并返回该元素所映射的值(也可以是不同类型的值). 具体的映射方式和返回值类型由闭包来指定. 当提供给

Java编程之Map中分拣思想。

题目:给定一个字符串,求出字符串中每一个单词在字符串中出现的次数 旨意:map的分拣思想. 每一个key的包装类,存放出现的次数 1 /** 2 * 作为包装类,用来存放英文单词,和该英文单词出现的次数 3 * @ClassName: Str 4 * @Description: TODO(这里用一句话描述这个类的作用) 5 * @author 尚晓飞 6 * @date 2014-7-30 下午6:57:29 7 * 8 */ 9 public class Str { 10 private St

Python中map,filter,reduce的应用

事例1: l=[('main', 'router_115.236.xx.xx', [{'abc': 1}, {'dfg': 1}]), ('main', 'router_183.61.xx.xx', [{'abc': 0}, {'dfg': 1}]), ('main', 'router_52.11.xx.xx', [{'abc': 0}, {'dfg': 1}]), ('main', 'router_183.17.xx.xx', [{'abc': 1}, {'dfg': 1}]) ] 检查参数l

3.python中map,filter,reduce以及内部实现原理剖析

一.map函数,对任何可迭代序列中的每一个元素应用对应的函数.(不管处理的是什么类型的序列,最后返回的都是列表.) 作用已经在标题中介绍过了,那么先来说说map函数的用法吧. map(处理逻辑可以是函数也可以是lambda表达式,可迭代的序列) 现在有一个列表. l1 = [1,2,3,4,5] 现在需要给这个列表里的每一个元素都+1.(当然,使用for循环可以做到对序列中的每个元素进行处理,但使用map函数会更加方便.) 首先,定义一个逻辑函数,要如何对序列中的每一个元素进行处理. def p

lambda,map,filter,reduce

lambda 编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数.返回一个函数对象. func = lambda x,y:x+y func相当于 def func(x,y): return x+y l = lambda x: x[0] if x else '' 可以直接调l对列表进行处理 map,reduce,filter中的function都可以用lambda表达式来生成 map map函数会根据提供的函数对指定序列做映射. m

python 内置函数 map filter reduce

map(函数名,可遍历迭代的对象) # 列组元素全加 10 # map(需要做什么的函数,遍历迭代对象)函数 map()遍历序列得到一个列表,列表的序号和个数和原来一样 l = [2,3,4,5,6,7,8] t = list(map(lambda x:x+10,l)) #遍历 l,l 里的元素全加10 map得到的结果是可迭代对象所以要list print(t) #===>[12, 13, 14, 15, 16, 17, 18] filter(函数名,可遍历迭代的对象) # filter(返回

python几个特别函数map filter reduce lambda

lambda函数也叫匿名函数,即,函数没有具体的名称.先来看一个最简单例子: def f(x): return x**2 print f(4) Python中使用lambda的话,写成这样 g = lambda x : x**2 print g(4) lambda表达式在很多编程语言都有对应的实现.比如C#: var g = x => x**2 Console.WriteLine(g(4)) 那么,lambda表达式有什么用处呢?很多人提出了质疑,lambda和普通的函数相比,就是省去了函数名称

python学习笔记-Day04-第三部分(内置函数,map,filter,reduce,yield)

map遍历序列,对其中的每个元素进行相应的操作,最终获得新的序列lst =[1,2,3,4]def fun(arg):    return arg+10new_lst = map(fun,lst) def fun2(a1,a2):    return a1+a2lst01 = [11,22,33]lst02 = [1,2,3]map(func2,lst01,lst02)  #序列的长度需要一致 或者 map(lambda a1,a2,a3:a1+a2,lst01,lst02) #########

day25 map,filter,reduce 内置函数,作业

=====================作业一#用map来处理字符串列表啊,把列表中所有人都变成sb,比方alex_sbname=['alex','wupeiqi','yuanhao']#######################################################def name_sb(x): return x+'_sb'#加 _sb 的函数res=map(name_sb,name)print(list(res))########################