Swift进阶之内建集合类型
数组
数组和可变性: 使用let定义的变量因为具有不变性,更有理由被优先使用。类似 let book = ...这样的声明时,可以确定book的值将永远不变。但这只针对值类型。如果使用let定义的类实例对象时,它只能保证这个引用永远不会变化,但这个引用指向的对象确实可以改变的。
swift数组提供了所有常规操作方法,像isEmpty或count,数组也允许直接使用特定的下标直接访问数组中的元素,但要注意不能越界。
迭代数组: for x in array
迭代除第一个元素外的其他数组元素: for x in array.dropFirst()
迭代除最后2个元素外的其他数组元素: for x in array.dropLast(2)
列举数组中的元素和对应的下标: for (index,element) in array.enumerated()
数组变形:对数组中的每个值执行转换操作。
Swift数组拥有map方法 let square = arr.map{arr in arr*arr} 这中形式有三个优势。首先是短,长度短一般意味着错误少,不过更重要的是代码清晰,所有无关代码内容都被移除了。其次,square将由map的结果得到,不会再改变他的值,所以就不再需要用var来声明了,我们可以将其声明为let。还有就是数组元素的类型可以从传递给map的函数中推断出来,所以就不再需要为square显示地指明类型了。
使用函数将行为参数化:标准库中有不下十多个函数接受调用者传入的闭包,并将它作为执行的关键步骤:
图中这些函数的目的都是为了摆脱代码中那些杂乱无用的部分,这些杂乱的部分都被一个单独的单词替代了。而且这些函数中有些拥有默认行为,除非进行过指定,比如sort默认会把可以作比较的元素按照升序排列。
可变和带有状态的闭包:举个例子
nums.map{itemintable.insert(item, at:nums.index(of: item)!)}
这个例子中,使用简单的for循环比使用map这样的函数是更好的选择。
Filter:检查一个数组,将这个数组中符合一定条件的元素过滤出来并用它们创建一个新的数组。nums.filter {num in num % 2 == 0} 使用Swift内建的用来代表参数的简写$0,这样代码会更加简短 nums.filter {$0 % 2 == 0}。对于很短的闭包,这样有助于提高代码可读性。如果闭包比较复杂,更好的做法应该是显示地把参数名写出来。一言概之:如果闭包可以很好地写在一行里,那么使用简写名会更适合。
通过组合的方式,可以轻易地完成很多数组操作,而不需要引入中间数组,这使得代码变得更短更易读。例如:
letnum = (1..<10).map{$0 * $0}.filter{$0 %2==0}
letnums = (1..<10).map{ (Int) ->Intin
returnInt * Int
}.filter{ (Int) ->Boolin
Int %2==0
}
上面两种方式的代码,都是通过map和filter组合使用,寻找1~10之间平方数是偶数的数字
Reduce:把所有元素合并为一个新的值。例如把元素的值全部加起来,有以下几种写法:
letresArr3 =intArr.reduce(10) {
$0 + $1
}
letnum =intArr.reduce(0) { (Result, Int) ->Intin
returnResult + Int
}
letnum1 =intArr.reduce(0,+)
filterMap:需要的是一个能够返回数组的函数作为变换参数。
实现:extension Array{
Func flatMap(_transform:(Element)->[T]->[T] {
var result:[T] = []
for x in self {
result.append(contentOf:transform(x))
}
return result
}
}
flatMap的一种常见使用场景是将不同数组里的元素进行合并。例如:
letsuits = ["♠","♥","♣","♦"]
letranks = ["J","Q","K","A"]
letresult =suits.flatMap{suitin
ranks.map({ rankin
(suit,rank)
})
}
数组类型:切片
除了通过单独的下标来访问数组中的元素,还可以通过下标来获取某个范围中的元素。例如获取除首个元素之外的其他元素:
letslice =intArr[1..
得到的结果类型是ArraySlice,而不是Array,切片类型只是数组的一种表达方式,数据仍是原来的数组,只不过用切片的方式来表示。这意味着原来的数组并不需要被复制。