首页 > Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性

Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性

1 数组排序

1.1 问题

本案例实现一个整型数组排序的函数,数组排序的规则由传递的规则函数决定。

1.2 方案

首先定义一个整型数组排序函数sortInts,该函数有一个整型数组类型的参数,该参数必须是输入输出参数inout,否则并不能修改数组的值。另外还有一个(Int,Int)->Bool函数类型的参数rule,该参数用于提供数组的排序规则。

然后实现函数sortInts,这里采用数组的冒泡排序算法来实现排序。

接下来实现一个数组排序的规则函数rule1,该函数是(Int,Int)->Bool类型,可以将该函数设置为sortInts函数rule1规则的默认值。

最后将一个整型数组a,传递给函数调用,就能实现数组a的排序。当然也可以自定义规则传递给函数sortInts。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义整型数组排序函数sortInts

首先定义一个整型数组排序函数sortInts,该函数有一个整型数组类型的参数,该参数必须是输入输出参数inout,否则并不能修改数组的值。另外还有一个(Int,Int)->Bool函数类型的参数rule,该参数用于提供数组的排序规则,代码如下所示:

  1. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool{
  2. }

然后实现函数sortInts,这里采用数组的冒泡排序算法来实现排序,代码如下所示:

  1. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool{
  2. forvari=0;i < data.count-1;i++ {
  3. forvar j=0;j.count-i-1;j++ {
  4. if rule(data[j], data[j+1]) {
  5. swap(&data[j], &data[j+1])
  6. }
  7. }
  8. }
  9. }

步骤二:实现规则函数

sortInts函数的rule参数是一个函数类型,需要调用时进行传递,该参数用于决定数组的排序规则,可以进行自定义,也就是由程序员来根据程序需求自定义排序规则。

接下来实现一个数组排序的规则函数rule1,该函数是(Int,Int)->Bool类型,可以将该函数设置为sortInts函数rule1规则的默认值,代码如下所示:

  1. func rule1(a:Int,b:Int)->Bool {
  2. return a > b
  3. }
  4. //函数类型作为参数传递
  5. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool = rule1{
  6. forvari=0;i < data.count-1;i++ {
  7. forvar j=0;j.count-i-1;j++ {
  8. if rule(data[j], data[j+1]) {
  9. swap(&data[j], &data[j+1])
  10. }
  11. }
  12. }
  13. }

最后将一个整型数组a,传递给函数调用,使用默认规则实现数组a的排序,代码如下所示:

  1. var a [1,3,2,4,9,8,5,0,6,7]
  2. sortInts(&a)

运行结果如图-1所示:

图-1

当然也可以自定义规则传递给函数sortInts,代码如下所示:

  1. //自定义排序规则
  2. func rule2(a:Int,b:Int)->Bool {
  3. return a
  4. }
  5. sortInts(&a, rule: rule2)
  6. func rule3(a:Int, b:Int)->Bool { return a%> b%3}
  7. sortInts(&a, rule: rule3)

运行结果如图-2所示:

图-2

1.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. func rule1(a:Int,b:Int)->Bool {
  3. return a > b
  4. }
  5. //函数类型作为参数传递
  6. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool = rule1{
  7. forvari=0;i < data.count-1;i++ {
  8. forvar j=0;j.count-i-1;j++ {
  9. if rule(data[j], data[j+1]) {
  10. swap(&data[j], &data[j+1])
  11. }
  12. }
  13. }
  14. }
  15. var a [1,3,2,4,9,8,5,0,6,7]
  16. sortInts(&a)
  17. a
  18. //自定义排序规则
  19. func rule2(a:Int,b:Int)->Bool {
  20. return a
  21. }
  22. sortInts(&a, rule: rule2)
  23. func rule3(a:Int, b:Int)->Bool { return a%> b%3}
  24. sortInts(&a, rule: rule3)
 

2 将Int数组转换为对应的String类型的数组

2.1 问题

如果需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。本案例在Array的map方法中使用尾随闭包将一个Int类型的数组[16, 58, 510]转换为对应的String类型的数组["一六", "五八", "五一零"]。

2.2 方案

Array类型有一个map方法,唯一参数是一个闭包表达式,数组中的每一个元素调用用一次该闭包函数,并返回该元素所映射的值,具体的映射方式由闭包表达式决定。

当提供给数组闭包函数后,map方法将返回一个新的数组,数组中包含了与原数组一一对应的映射后的值。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建字典digiNames

创建一个数字和中文名映射的字典digiNames,代码如下所示:

  1. letdigitNames [
  2. 0"零"1"一"2"二"3"三"4"四",5"五"6"六"7"七"8"八"9"九"]
  3. let numbers [1658510]

步骤二:调用map方法

numbers数组调用map方法,该方法需要传递一个闭包表达式用于规定映射规则,这里采用尾随闭包的形式,代码如下所示:

  1. numbers.map { (var number-> String in
  2. var output ""
  3. while number {
  4. //字典下标返回一个可选值
  5. output = digitNames[number 10]! + output
  6. number /= 10
  7. }
  8. return output
  9. }

map函数是数组的方法,可以迭代数组中每一元素传入闭包执行一次,并将执行后的结果做成一个数组返回回来,运行结果如图-3所示:

图-3

2.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. letdigitNames [
  3. 0"零"1"一"2"二"3"三"4"四",5"五"6"六"7"七"8"八"9"九"]
  4. let numbers [1658510]
  5. //map函数是数组的方法,可以迭代数组中每一元素传入闭包执行一次,并将执行后的结果做成一个数组返回回来
  6. let strings = numbers.map { (var number)->String in
  7. var output ""
  8. while number {
  9. output = digitNames[number%10]!+output
  10. number/=10
  11. }
  12. return output
  13. }
  14. strings
 

3 定义商品条形码的枚举

3.1 问题

假设一个仓库跟踪系统需要利用两种不同类型的条形码来跟踪商品,有些商品上标有UPC-A格式的一维码,它是由三个整型数字组成。另外其他一些商品上标有QR格式的二维码,它是一个字符串,如图-4、图-5所示:

图-4

图-5

本案例要求使用枚举来表示商品条码并设置其关联值。

3.2 方案

首先把UPC-A码作为三个整型值的元组,把QR码作为一个任字符串存储起来,那么定义一个枚举Barcode并设置器关联值。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义枚举Barcode

定义一个枚举Barcode表示商品条形码,它有两个成员UPCA和QRCode,UPCA的关联值是一个包含三个整型值的元组类型,QRCode的关联值是一个String类型,代码如下所示:

  1. enum Barcode{
  2. case UPCA(Int, Int, Int)
  3. caseQRCode(String)
  4. }

枚举的定义不提供任何Int或String的实际值,只是定义而已。

步骤二:使用关联值

使用刚才定义的枚举类型Barcode创建一个新的变量productBarcode,并且赋给它两个成员的关联值,代码如下所示:

  1. varproductBarCode : Barcode = Barcode.UPCA(6925303723750)
  2. productBarCode = Barcode.QRCode("ABCDEFSFD")

不同的条形码可以使用一个switch语句来检查,代码如下所示:

  1. switchproductBarCode {
  2. case .UPCA(let(num, id, check)):
  3. println("这是条形码(num)-(id)-(check)")
  4. case .QRCode(let pCode):
  5. println("这是二维码(pCode)")
  6. }

然后调用函数,运行结果如图-6所示:

图-6

3.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. //关联值
  3. enum Barcode{
  4. case UPCA(Int, Int, Int)
  5. caseQRCode(String)
  6. }
  7. varproductBarCode : Barcode = Barcode.UPCA(6925303723750)
  8. productBarCode = Barcode.QRCode("ABCDEFSFD")
  9. switchproductBarCode {
  10. case .UPCA(let(num, id, check)):
  11. println("这是条形码(num)-(id)-(check)")
  12. case .QRCode(let pCode):
  13. println("这是二维码(pCode)")
  14. }
 

4 定义几何形状的结构体

4.1 问题

属性分为存储属性和计算属性,存储属性就是用常量或变量保存的属性值。计算属性的值是通过计算得出的。

按如下要求完成本案例:

1)定义一个Point结构体,用于表示点坐标(x,y);

2)定义一个Size结构体,用于表示形状的长和宽(width,height);

3)定义一个Rect结构体,用于表示有原点和尺寸的矩形,还提供一个表示中心点center的计算属性;

4)创建一个Rect类型的实例square,并设置和修改center属性移动矩形,如图-7所示:

图-7

4.2 方案

首先定义Point结构体和Size结构体,Point结构有两个存储属性x和y,用于表示点坐标。Size结构体也有两个存储属性width和height,用于表示长宽。

然后定义矩形Rect结构体,该结构体有两个存储属性一个是Point类型的origin,用于表示原点坐标,另一个是Size类型的size,用于表示矩形的长宽。

Rect结构体还有一个Point类型的计算属性center,用于表示矩形的中心点,需要提供getter和setter方法获取和设置其值。

最后创建一个Rect实例square,设置和修改center属性,查看输出结果。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义Point和Size结构体

首先定义Point结构体和Size结构体,Point结构有两个存储属性x和y,用于表示点坐标。Size结构体也有两个存储属性width和height,用于表示长宽,代码如下所示:

  1. struct Point {
  2. //存储属性
  3. var x 0.0
  4. var y 0.0
  5. }
  6. struct Size {
  7.      //存储属性
  8. var width 0.0
  9. var height 0.0
  10. }

步骤二:定义Rect结构体

然后定义矩形Rect结构体,该结构体有两个存储属性一个是Point类型的origin,用于表示原点坐标,另一个是Size类型的size,用于表示矩形的长宽,代码如下所示:

  1. structRect {
  2. //存储属性
  3. var origin Point()
  4. var size Size()
  5. }

Rect结构体还有一个Point类型的计算属性center,用于表示矩形的中心点,需要提供getter和setter方法获取和设置其值,代码如下所示:

  1. structRect {
  2. //存储属性
  3. var origin Point()
  4. var size Size()
  5. //计算属性
  6. varcenter:Point {
  7. get {
  8. letcenterX = origin.x + size.width/2
  9. letcenterY = origin.y + size.height/2
  10. return Point(x: centerX, y: centerY)
  11. }
  12. set(newCenter{
  13. origin.x = newCenter.x - size.width/2
  14. origin.y = newCenter.y - size.height/2
  15. }
  16. }
  17. }

步骤三:创建square实例

创建一个Rect实例square,原点坐标设置为(0.0,0.0),长宽设置为(10.0,10.0),可以通过点运算调用getter方法获取到center属性的值,代码如下所示:

  1. var square Rect(originPoint(x0.0, y0.0), sizeSize(width10.0, height10.0))
  2. letcenterSquare = square.center

可以看到center的值为(5.0,5.0),运行结果如图-8所示:

图-8

然后重新设置center的值(15,15),设置属性center的值会调用setter来修改该属性origin的值,代码如下所示:

  1. square.center Point(x15, y15)

可以看到此时square的origin属性的值为(10,10),运行结果如图-9所示:

图-9

4.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. struct Point {
  3. //存储属性
  4. var x 0.0
  5. var y 0.0
  6. }
  7. struct Size {
  8. //存储属性
  9. var width 0.0
  10. var height 0.0
  11. }
  12. structRect {
  13. //存储属性
  14. var origin Point()
  15. var size Size()
  16. //计算属性
  17. varcenter:Point {
  18. get {
  19. letcenterX = origin.x + size.width/2
  20. letcenterY = origin.y + size.height/2
  21. return Point(x: centerX, y: centerY)
  22. }
  23. set(newCenter{
  24. origin.x = newCenter.x - size.width/2
  25. origin.y = newCenter.y - size.height/2
  26. }
  27. }
  28. }
  29. var square Rect(originPoint(x0.0, y0.0), sizeSize(width10.0, height10.0))
  30. letcenterSquare = square.center
  31. square.center Point(x15, y15)

转载于:https://www.cnblogs.com/hytx/p/5053776.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 学习目标:了解什么是数组;数组如何访问内存地址(一维,二维);什么是数组是由相同类型的元素的集合所组成的数据结构,分配一块连续的内存来存储。利用元素的索引可以计算出该元素对应的存储地址。 最简单的数据结构类型是一维数组。数组如何实现随机访问?数组是一种线性表数据结构,用一直连续的内存空间来储存一组具有相同类型的数据。根据数组的特性(连...

  • 一、静态数据及动态数组的创建     静态数据:               int a[10];             int a[]={1,2,3};             数组的长度必须为常量。     动态数组:             int len;             int *a=new int...

  • 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例 1: 给定 nums = [3,2,2,3], val...

  • 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 示例 1: 给定数组 nums = [1,1,2],  函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2...

  • 文章目录1. 数组的声明2. 数组元素的遍历3. 数组的截取4. Go 语言的切片5. 数组 和 切片的共同点...

  • 原文出处: 韩昊    1 2 3 4 5 6 7 8 9 10 作 者:韩 昊 知 乎:Heinrich 微 博:@花生油工人 知乎专栏:与时间无关的故事   谨以此文献给大连海事大学的吴楠老师,柳晓鸣老师,王新年老师以及张晶泊老师。   转载的同学请保留上面这句话,谢谢。如果还能保留文章来源就更感激不尽了。 我保证这篇文章...

  • 原文出处: 韩昊   我保证这篇文章和你以前看过的所有文章都不同,这是 2012 年还在果壳的时候写的,但是当时没有来得及写完就出国了……于是拖了两年,嗯,我是拖延症患者…… 这篇文章的核心思想就是: 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维...

  • 很多Linux高手都喜欢使用screen命令,screen命令可以使你轻松地使用一个终端控制其他终端。尽管screen本身是一个非常有用的工具,byobu作为screen的增强版本,比screen更加好用而且美观,并且提供有用的信息和快捷的热键。 想象一下这样一个场景:你通过Secure Shell(ssh)链接到一个服务器,并...

  • NarrowbandPrimary Synchronization Signal时域位置每1个SFN存在一个NPSSSFNSubframeSymbol长度每个SFN5最后11个symbol11个symbols频域位置NB-IOT下行带宽固定180kHz,一个PRB,12个子载波。...

  •  [h1]反斜杠只能够阻止一个字符  [h2]位于键盘的左上角,和~公用一个键。...