数组截取的一些方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 let arr = [1 , 2 , 3 , 4 , 5 ]print ("startIndex:\(arr.startIndex) , endIndex:\(arr.endIndex) " )let slice1 = arr.dropFirst(2 )print ("startIndex:\(slice1.startIndex) , endIndex:\(slice1.endIndex) " )let slice2 = arr.dropFirst().dropLast()print ("startIndex:\(slice2.startIndex) , endIndex:\(slice2.endIndex) " )let rs = arr.dropFirst().prefix(upTo: 3 )print (rs) let rs1 = arr.dropFirst().prefix(3 )print (rs1) let fib = [1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 ]let slfib = fib[1 ... 5 ]print ("startIndex:\(slfib.startIndex) , endIndex:\(slfib.endIndex) " )print (slfib) let prefixArr0 = arr.prefix(upTo: arr.startIndex)print (prefixArr0) let prefixArr = arr.prefix(upTo: 3 )print (prefixArr) let prefixArr1 = arr.prefix(upTo: arr.endIndex)print (prefixArr1) let prefixArr2 = slfib.prefix(upTo: 3 ) print (prefixArr2) let preArr2 = arr.prefix(2 )print (preArr2) let preArr3 = arr.prefix(through: 4 )print (preArr3) let suffixArr0 = arr.suffix(from: arr.startIndex)print (suffixArr0) let suffixArr00 = arr.suffix(from: arr.endIndex)print (suffixArr00) let suffixArr = arr.suffix(from: 3 )print (suffixArr) let suffixArr2 = slfib.suffix(from: 3 ) print (suffixArr2) let suffixArr1 = arr.suffix(0 )print (suffixArr1) let rangeArr = arr[3 ... 3 ]print (rangeArr) let rangeArr1 = arr[2 ..< 4 ]print (rangeArr1) let rangeArr2 = arr[2 ... ]print (rangeArr2) let rangeArr3 = arr[..< 3 ]print (rangeArr3) let rangeArr4 = arr[5 ..< 5 ]print (rangeArr4) let rangeArr5 = arr[5 ... ]print (rangeArr5) let dropFirstArr = arr.dropFirst(3 )print (dropFirstArr) let dropLastArr = arr.dropLast(3 )print (dropLastArr)
上述操作之后得到的都是数组切片类型,而不是数组类型。这里简单介绍一下ArraySlice 类型,因为上面有些方法是跟索引相关的,比如方法prefix(upTo end: Int),而ArraySlice 类型的startIndex并不总是从0开始,所以得到的结果可能出乎你的预料。
ArraySlice 类型官方文档:
The ArraySlice type makes it fast and efficient for you to perform operations on sections of a larger array. Instead of copying over the elements of a slice to new storage, an ArraySliceinstance presents a view onto the storage of a larger array. And because ArraySlice presents the same interface as Array, you can generally perform the same operations on a slice as you could on the original array.
Unlike Array and ContiguousArray, the starting index for an ArraySlice instance isn’t always zero. Slices maintain the same indices of the larger array for the same elements, so the starting index of a slice depends on how it was created, letting you perform index-based operations on either a full array or a slice.
ArraySlice是Array, ContiguousArray, or ArraySlice 实例的一个切片。但是它并不会将切片中的元素拷贝到一个新的存储空间,而是依然指向原始数组。
注意:endIndex始终指向集合最后一个元素的后一个位置。系统的很多方法涉及到索引时都会跟startIndex和endIndex相关。而不是0和数组个数。
ArraySlice的startIndex并不总是从0开始 ,而是取决于它的创建方式。下面的例子中可以看到slice1的startIndex是2而不是0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let arr = [1 , 2 , 3 , 4 , 5 ]print ("startIndex:\(arr.startIndex) , endIndex:\(arr.endIndex) " )let slice1 = arr.dropFirst(2 )print ("startIndex:\(slice1.startIndex) , endIndex:\(slice1.endIndex) " )let slice2 = arr.dropFirst().dropLast()print ("startIndex:\(slice2.startIndex) , endIndex:\(slice2.endIndex) " )let rs = arr.dropFirst().prefix(upTo: 3 )print (rs) let rs1 = arr.dropFirst().prefix(3 )print (rs1)
接下来解释一下arr.dropFirst().prefix(upTo: 3)的结果为什么是[2, 3],而不是[2, 3, 4]。
首先arr.dropFirst()将得到一个切片[2, 3, 4, 5],它的startIndex为1,endIndex为5。prefix(upTo: 3)表示从startIndex开始取到索引为3的元素(不包括),而切片的startIndex为1,所以这里只会取索引为1,2的元素,所以结果为[2, 3]。而prefix(3)表示取前3个,所以结果为[2, 3, 4]。
参考
ArraySlice
WWDC 2018:在Swift中如何高效地使用集合