Swift的高阶函数

  • swift常用高阶函数
    • 1. map
    • 2. flatMap
    • 3. filter
    • 4. reduce

swift常用高阶函数

swift中比较常用的高阶函数有:map、flatMap、filter、reduce
更多swift相关教程可以参考极客学院文章

1. map

map可以对数组中的每一个元素做一次处理

  1. 先通过下面实例代码了解一下map的用法
// 计算字符串的长度
let stringArray = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]
func stringCount(string: String) -> Int {return string.characters.count
}
stringArray.map(stringCount)stringArray.map({string -> Int inreturn string.characters.count
})// $0代表数组中的每一个元素
stringArray.map{return $0.characters.count
}
  1. 我们来查看一下map在swift中的定义
    我们看到它可以用在 Optionals 和 SequenceType 上(如:数组、词典等)。
    代码:
public enum Optional<Wrapped> : _Reflectable, NilLiteralConvertible {/// If `self == nil`, returns `nil`.  Otherwise, returns `f(self!)`.@warn_unused_resultpublic func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U?
}extension CollectionType {/// Returns an `Array` containing the results of mapping `transform`/// over `self`.////// - Complexity: O(N).@warn_unused_resultpublic func map<T>(@noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]
}

源码中的一些关键字在这里介绍一下:
@warn_unused_result:表示如果没有检查或者使用该方法的返回值,编译器就会报警告。
@noescape:表示transform这个闭包是非逃逸闭包,它只能在当前函数map中执行,不能脱离当前函数执行。这使得编译器可以明确的知道运行时的上下文环境(因此,在非逃逸闭包中可以不用写self),进而进行一些优化

  1. 对 Optionals进行map操作
    简要的说就是,如果这个可选值有值,那就解包,调用这个函数,之后返回一个可选值,需要注意的是,返回的可选值类型可以与原可选值类型不一致:
///原来类型: Int?,返回值类型:String?
var value:Int? = 1
var result = value.map { String("result = \($0)") }
/// "Optional("result = 1")"
print(result)var value:Int? = nil
var result = value.map { String("result = \($0)") }
/// "nil"
print(result)
  1. 对SequenceType进行map操作

我们可以使用map方法遍历数组中的所有元素,并对这些元素一一进行一样的操作(函数方法)。map方法返回完成操作后的数组。


我们可以对比一下用传统的For-in操作和map操作:

1. 传统写法:
var values = [1,3,5,7]
var results = [Int]()
for var value in values {value *= 2results.append(value)
}
//"[2, 6, 10, 14]"
print(results)
//传统的For-in实现起来代码很多,不简介,而且效率没有高阶函数高。2. 使用map高阶函数
let results = values.map ({ (element) -> Int inreturn element * 2
})
//"[2, 6, 10, 14]"此外还有更加精简的写法:
let results = values.map { $0 * 2 }
//"[2, 6, 10, 14]"
3.

通过上面的代码对比,我们可以看出高阶函数精简写法是多么的优雅,就像写诗一样。下面我们来探究一下怎么就精简这么短小了呢,连return语句都不需要了

  • 第一步
    由于闭包的函数体很短,所以我们将其改写成一行:
let results = values.map ({ (element) -> Int in return element * 2 })
//"[2, 6, 10, 14]"
  • 第二步
    由于我们的闭包是作为map的参数传入的,系统可以推断出其参数与返回值,因为其参数必须是(Element) -> Int类型的函数。因此,返回值类型,->及围绕在参数周围的括号都可以被忽略:
let results = values.map ({ element  in return element * 2 })
//"[2, 6, 10, 14]"
  • 第三步
    单行表达式闭包可以通过省略return来隐式返回闭包的结果:
    由于闭包函数体只含有element * 2这单一的表达式,该表达式返回Int类型,与我们例子中map所需的闭包的返回值类型一致(其实是泛型),所以,可以省略return。
let results = values.map ({ element  in element * 2 })
//"[2, 6, 10, 14]"
  • 第四步
    参数名称缩写(Shorthand Argument Names),由于Swift自动为内联闭包提供了参数缩写功能,你可以直接使用$0,$1,$2…依次获取闭包的第1,2,3…个参数。
    如果您在闭包表达式中使用参数名称缩写,您可以在闭包参数列表中省略对其的定义,并且对应参数名称缩写的类型会通过函数类型进行推断。in关键字也同样可以被省略:
let results = values.map ({ $0 * 2 })//$0即代表闭包中的第一个参数。
//"[2, 6, 10, 14]"
  • 第五步
    尾随闭包,由于我们的闭包是作为最后一个参数传递给map函数的,所以我们可以将闭包表达式尾随:
let results = values.map (){ $0 * 2 }
//"[2, 6, 10, 14]"

如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把()省略掉:

let results = values.map { $0 * 2 }
//"[2, 6, 10, 14]"

2. flatMap

  1. flatMap返回后的数组中不存在nil,同时它会把Optional解包
let array = ["Apple", "Orange", "Puple", ""]let arr1 = array.map { a -> Int? inlet length = a.characters.countguard length > 0 else { return nil }return length
}
arr1 // [{some 5}, {some 6}, {some 5}, nil]let arr2 = array.flatMap { a-> Int? inlet length = a.characters.countguard length > 0 else { return nil}return length
}
arr2 // [5, 6, 5]
  1. flatMap还能把数组中存有数组的数组(二维数组、N维数组)一同打开变成一个新的数组
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]let arr1 = array.map{ $0 }
arr1 // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]let arr2 = array.flatMap{ $0 }
arr2 // [1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. flatMap也能把两个不同的数组合并成一个数组,这个合并的数组元素个数是前面两个数组元素个数的乘积
let fruits = ["Apple", "Orange", "Puple"]
let counts = [2, 3, 5]let array = counts.flatMap { count infruits.map ({ fruit inreturn fruit + "  \(count)"            })
}
array // ["Apple 2", "Orange 2", "Puple 2", "Apple 3", "Orange 3", "Puple 3", "Apple 5", "Orange 5", "Puple 5"]

3. filter

filer:过滤,可以对数组中的元素按照某种规则进行一次过滤

// 筛选出字符串的长度小于10的字符串
let stringArray = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]
func stringCountLess10(string: String) -> Bool {return string.characters.count < 10
}
stringArray.filter(stringCountLess10)stringArray.filter({string -> Bool inreturn string.characters.count < 10
})// $0表示数组中的每一个元素
stringArray.filter{return $0.characters.count < 10
}

4. reduce

reduce:计算,可以对数组的元素进行计算

// 将数组中的每个字符串用‘、’拼接
let stringArray = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]func appendString(string1: String, string2: String) -> String {return string1 == "" ? string2 : string1 + "、" + string2
}
// reduce方法中的第一个参数是初始值
stringArray.reduce("", appendString)stringArray.reduce("", {(string1, string2) -> String inreturn string1 == "" ? string2 : string1 + "、" + string2
})// $0表示计算后的结果, $1表示数组中的每一个元素
stringArray.reduce("", {return $0 == "" ? $1 : $0 + "、" + $1
})

参考博客,教程:
http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html

Swift的高阶函数相关推荐

  1. Swift 常用高阶函数

    Swift 常用高阶函数 map函数 对每一个元素进行运算 计算每一个元素的count 对元素进行大小写变换 转换类型 sorted函数 从小到大排序 从大到小排序 flatMap函数 降维 过滤元素 ...

  2. Swift 基础 高阶函数 forEach filter map compactMap compactMapValues flatMap reduce sort sorted shuffled ...

    一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹.靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希 ...

  3. Swift 烧脑体操(三) - 高阶函数

    前言 \\ Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说 ...

  4. Swift 中的高阶函数

    一.概念 高阶函数是将一个或多个函数作为参数或返回一个函数作为其结果的函数 二.Swift的集合类型中的高阶函数 1.Map 对于原始集合里的每一个元素,以一个变换后的元素替换之形成一个新的集合 le ...

  5. Go 学习笔记(61)— Go 高阶函数、函数作为一等公民(函数作为输入参数、返回值、变量)的写法

    函数在 Go 语言中属于"一等公民(First-Class Citizen)"拥有"一等公民"待遇的语法元素可以如下使用 可以存储在变量中: 可以作为参数传递给 ...

  6. 2021年大数据常用语言Scala(三十七):scala高级用法 高阶函数用法

    目录 高阶函数用法 作为值的函数 匿名函数 柯里化(多参数列表) 闭包 高阶函数用法 Scala 混合了面向对象和函数式的特性,在函数式编程语言中,函数是"头等公民",它和Int. ...

  7. Koltin 高阶函数

    高阶函数 高阶函数是将函数用作参数或返回值的函数. 在java中函数和方法是同一个概念, 我就把高阶函数理解为:高阶函数是将方法用作参数或返回值的方法, java中我们要调用方法里面的参数一般需要实现 ...

  8. 函数 tostring_Kotlin实战之Fuel的高阶函数

    Fuel 是一个用 Kotlin 写的网络库,与 OkHttp 相比较,它的代码结构比较简单,但是它的巧妙之处在于充分利用了 Kotlin 的语言特性,所以代码看上去干净利落. OkHttp 使用了一 ...

  9. 【廖雪峰Python学习笔记】高阶函数

    Higher-order function 高阶函数 映射 过滤算法 排序算法 高阶函数 变量可指向函数 >>> abs # 函数 <built-in function abs ...

最新文章

  1. 两个主键怎么设置tsql_索引该怎么创建?
  2. 时间计算题100道_2019四校及分校自招开放日情况汇总(含时间安排、考试内容难度、到场人数等)...
  3. React-Native 组件开发方法
  4. 代数学笔记5: 群论(一)
  5. mkpasswd命令使用方法
  6. 每一个与众不同的水瓶座
  7. 感谢微软BPOS4China技术支持组
  8. 绕过PDF阅读编辑要VIP才能无水印保存的方法
  9. 淘淘商城第59讲——搭建Solr集群
  10. SDRAM内存条时序特点
  11. androidmmi可以卸载吗_删除Android自带的系统软件注意事项
  12. 解决-最新版Google谷歌浏览器谷歌浏览器Chrome一上传或者下载附件图片就未响应卡死
  13. 烤鱼界头牌半天妖发文致歉,背后暴露了哪些问题?
  14. python复杂网络点图可视化_数据分析:R与Python怎么选?
  15. 微信小程序接入腾讯云MQTT服务
  16. 从汇编角度看一个C函数调用
  17. java8 List操作
  18. 微信群机器人自动管理系统源码
  19. 博图程序的归档和恢复
  20. Linux基本命令讲解

热门文章

  1. 模型数据处理之删除重复点和重复面
  2. 毕业论文知识点记录(二)——环境数据下载之全球土壤数据下载(非时序性)
  3. 跨境电商独立站的玩法介绍-扬帆际海
  4. IntelliJ IDEA 怎么导入项目
  5. 零基础ECharts 图表 使用 步骤 流程图 详解 与 pc 端自适应
  6. 图像算法:数字图像处理程序大全
  7. np.power函数与内置函数的简单区别
  8. Vue全家桶(一)之基础指令
  9. 头条后台实习面试(二面挂)
  10. Telnet远程登入,简单易懂