print(element)
请点击链接:[Swift]forEach详解
3.9 startIndex、endIndex
startIndex:数组第一个元素的索引。
endIndex:数组最后一个元素的索引的下一位。
1 var arr = [1,2,3,4,5]
3 //startIndex是数组第一个元素的索引
4 print(arr[arr.startIndex])
5 //Print 1
7 print(arr[arr.startIndex..<arr.endIndex])
8 //Print [1, 2, 3, 4, 5]
10 //注意endIndex不是数组最后一个元素的索引
11 print(arr[..<arr.endIndex])
12 //Print [1, 2, 3, 4, 5]
四、数组特殊方法
4.1 filter
(1)直接过滤数组元素,返回满足符合条件的新数组。
1 var arr = [1,2,3,4,5]
2 //$0表示arr中的元素
3 //返回大于2的元素组成的数组
4 let filterArr = arr.filter { $0 > 2 }
(2)传入一个闭包函数作为参数,作为判断条件,返回满足符合条件的新数组。
1 var arr = ["123Z","456Z","789"]
2 let filterArr = arr.filter { (str) -> Bool in
3 return str.contains("Z")}
4 print(filterArr)
5 //Print ["123Z", "456Z"]
4.2 map
将原来数组中的元素映射到新的数组中,映射数组元素,转化元素类型。
map函数以一个闭包函数作为参数,返回一个新的数组,编译器会自动根据调用它的数组类型自动推断出返回数组的类型。
1 var arr = [1,2,3,4,5]
2 //映射成字符串类型
3 let mapArr1 = arr.map { (num) -> String in
4 return "\(num)" + "Z"
6 print(mapArr1)
7 //Print ["1Z", "2Z", "3Z", "4Z", "5Z"]
10 //将数组中每个元素的值乘以3
11 let mapArr2 = (1...5).map{$0*3}
12 print(mapArr2)
13 //Print [3, 6, 9, 12, 15]
4.3 flatMap
flatMap方法是在map方法的基础上增加新的功能。
(1) 空值过滤:调用flatMap生成的新数组过滤掉了nil值的元素,得到的新数组里面全部都是非nil得元素。
String类型
1 let arr = ["1", "2", "3", "4", nil]
2 let newArr = arr.flatMap { $0 }
3 print(newArr)
4 //Print ["1", "2", "3", "4"]
Int类型
1 let arr = [1, 2, 3, 4, nil]
2 let newArr = arr.flatMap { $0 }
3 print(newArr)
4 //Print [1, 2, 3, 4]
(2) 强解包:flatMap自动帮我们做了解包的工作,不用去解包元素。以map方法进行对比。
1 //以map方法进行对比
2 let arr1:[String?] = ["123", "456", "789"]
3 let newArr1 = arr1.map { $0 }
4 print(newArr1)
5 //Print [Optional("123"), Optional("456"), Optional("789")]
7 //flatMap
8 let arr2:[String?] = ["123", "456", "789"]
9 let newArr2 = arr2.flatMap { $0 }
10 print(newArr2)
11 //Print ["123", "456", "789"]
(3) 数组压平解嵌套数组:指是把一个二维数组里面的元素(数组)展开成一维数组。
检查数组中有没有嵌套数组,把嵌套的数据结构再重组成一个数组。
1 var arr = [[1], [2], [3], [4], [5]]
2 let flatMapArr = arr.flatMap{ $0 }
3 //压平解嵌套数组
4 print(flatMapArr)
5 // Print [1, 2, 3, 4, 5]
请点击链接:[Swift]多维数组的表示和存储:N维数组映射到一维数组(一一对应)!
4.4 compactMap
过滤数组中出现的nil和可选类型。
可以把一个集合中的空值去除,并且返回一个去除nil值得数组
1 let numbers = [1, 2,nil, 5]
3 //compactMap
4 let compactMapResult = numbers.compactMap { (number) -> Int? in
5 return number
7 print(compactMapResult)
8 //Print [1, 2, 5]
10 //map
11 let mapResult = numbers.map { (number) -> Int? in
12 return number
13 }
14 print(mapResult)
15 //Print [Optional(1), Optional(2), nil, Optional(5)]
4.5 reduce
可以把数组变成一个元素,首先需要指定一个初始值,然后在闭包中写一个reduce的规则,接着reduce方法会开始递归的对数组中的元素进行闭包运算,直到算出最后一个结果。
注意还可以用于其他符号,不只是四则运算符。
1 //第一个参数为用来运算的初始值。
2 //依次用第二个参数的运算符号与数组元素进行算术运算。
4 //数组所有元素之和
5 print((1...5).reduce(0, +))
6 //Print 15
8 //数组所有元素之差
9 print((1...5).reduce(0, -))
10 //Print -15
12 //数组所有元素之积
13 print((1...5).reduce(1, *))
14 //Print 120
16 //数组所有元素之商
17 print((1...5).reduce(120, /))
18 //Print 1
20 //数组所有元素异或:相同为0,不同为1
21 print([1,1].reduce(0, ^))
22 //Print 0
23 print([1,1,1].reduce(0, ^))
24 //Print 1
将数组元素连接成字符串并添加指定内容,闭包和简写形式:
1 var arr = [1,2,3,4,5]
2 //闭包形式
3 let newArr1 = arr.reduce("strengthen") { (a1, a2) -> String in
4 return "\(a1)" + "\(a2)"}
5 print(newArr1)
6 //Print strengthen12345
8 //简写形式
9 let newArr2 = arr.reduce("Z"){ "\($0)" + "\($1)" }
10 print(newArr2)
11 //Print Z12345
4.6 prefix、suffix
获取数组从头或从尾开始的一段片段。
1 var arr = [1,2,3,4,5]
2 //prefix:从头部开始截取
3 //upTo:[0,3),不包含第三个元素的索引:0,1,2
4 let prefixArr = arr.prefix(upTo: 3)
5 print(prefixArr)
6 //Print [1, 2, 3]
8 //suffix:截取至尾部
9 //从第三个元素到末尾,包含第三个元素的索引:3,4
10 let suffixArr = arr.suffix(from: 3)
11 print(suffixArr)
12 //Print [4, 5]
4.7 dropFirst()、dropLast()
与prefix、suffix互补的方法,获得删除从头部或尾部开始的区间元素后的数组。
1 var arr = [1,2,3,4,5]
2 //从头部开始删除三个元素
3 let dropFirstArr = arr.dropFirst(3)
4 print(dropFirstArr)
5 //Print [4, 5]
7 //从尾部开始删除三个元素
8 let dropLastArr = arr.dropLast(3)
9 print(dropLastArr)
10 //Print [1, 2]
4.8 验证字符串中是否包含某个单词
1 let words = ["Strengthen","Swift","iOS"]
2 let sentence = "My name is Strengthen"
4 //方法1:filter
5 let result1 = !words.filter({sentence.contains($0)}).isEmpty
6 print(result1)
7 //Print true
9 //方法2:contains
10 let result2 = words.contains(where: sentence.contains)
11 print(result2)
12 //Print true
14 //方法3:拆分
15 let result3 = sentence.characters
16 .split(separator: " ")
17 .lazy
18 .map(String.init)
19 .contains(where: Set(words).contains)
20 print(result3)
21 //Print true
4.9 埃拉托色尼选筛法(求小于N的所有质数)
1 let number = 100
2 var primes = Set(2...number)
3 (2...Int(sqrt(Double(number)))).forEach {
4 let _ = primes.subtract(stride(from: 2*$0, through: number, by: $0))
6 print(primes.sorted())
7 //Print [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
4.10 elementsEqual
比较数组相等或以特定元素开始。对这类操作,需要提供两个内容,一个是要比较的数组,另一个则是比较的规则
1 var arr = [1,2,3]
2 //比较另一个数组的各元素是否时原数组各元素的两倍
3 let result1 = arr.elementsEqual([2,4,6], by: { $0*2 == $1 })
4 print(result1)
5 //Print true
7 //比较从头部开始的元素区间是否相同
8 let result2 = arr.starts(with: [1,2], by: { $0 == $1 })
9 print(result2)
10 //Print true
4.11 partition
partition(by:)
则会先对传递给它的数组进行重排,然后根据指定的条件在重排的结果中返回一个分界点位置。
这个分界点分开的两部分中:前半部分的元素都不满足指定条件;后半部分都满足指定条件。
这样就可以使用range operator来访问者两个区间形成的Array
对象。
1 var arr = [1,2,3,4,5]
3 //条件:大于3
4 let privot1 = arr.partition(by: { $0 > 3 })
5 print(privot1)
6 //Print 3
8 //前半部分是不符合条件的元素
9 print(arr[0..<privot1])
10 //Print [1, 2, 3]
12 //后半部分是符合条件的元素
13 print(arr[privot1..<arr.endIndex])
14 //Print [4, 5]
17 //条件:小于3
18 let privot2 = arr.partition(by: { $0 < 3 })
19 print(privot2)
20 //Print 3
22 //前半部分是不符合的元素
23 print(arr[0..<privot2])
24 //Print [5, 4, 3]
26 //后半部分是符合条件的元素
27 print(arr[privot2..<arr.endIndex])
28 //Print [[2, 1]
4.12 contains
contains
的一个好处就是只要遇到满足条件的元素,函数的执行就终止了。
基于这个contains
,还可以给Array
添加一个新的方法,用来判断Array
中所有的元素是否满足特定的条件。
1 var arr = [1,2,3,4,5]
2 //判断是否包含偶数
3 let result = arr.contains{ $0 % 2 == 0}
4 print(result)
5 //Print true
4.13 交换数组中元素的值
请点击链接:[Swift]Array数组的swapAt函数
4.14 forEach:
请点击链接:[Swift]forEach详解
注意,在forEach闭包中,return不会中断整个遍历。
4.15 sorted:排序
请点击链接:[Swift]数组排序:sort和sorted
4.16.字符串直接转换成字符数组或字符串数组
1 let str:String = "strengthen"
2 //方法1:转换为字符数组
3 var arr1:[Character] = Array(str)
4 print(arr1)
5 //Print ["s", "t", "r", "e", "n", "g", "t", "h", "e", "n"]
7 //方法2:转换为字符串数组
8 var arr2:[String] = str.map{ String($0) }
9 print(arr2)
10 //Print ["s", "t", "r", "e", "n", "g", "t", "h", "e", "n"]
五、NSArray与Array
(1)Array是一个结构体,是值类型。
在Swift中,Array
是按照值语义实现的,当我们复制一个Array对象时,会拷贝整个Array
的内容。
(2)NSArray是一个类,是引用类型。
在Foundation中,数组这个类型有两点和Swift的Array
是不同的:
数组是否可以被修改时通过NSArray和NSMutableArray这两个类型来决定的
NSArray
和NSMutableArray
都是类对象,复制他们执行的是引用语义
var arr: [NSObject] = [1 as NSObject,"swift" as NSObject]