Is there a cleaner way to get the last two items of an array in Swift? In general, I try to avoid this approach since it\'s so easy to be off-by-one with the indexes. (Using
let items = [0, 2, 5, 3, 7, 6, 9, 10]
let count = items.count
let last2 = items[count - 2 ..< count] // [9, 10]
in swift 5 you can use suffix for get objects from the last and use prefix for get objects from the first, here is an example:
let exampleArray = ["first text", "second text", "third text"]
let arr1 = exampleArray.suffix(2) // ["second text", "third text"]
let arr2 = exampleArray.prefix(2) // ["first text", "second text"]
The result is a slice, but you can coerce it to an Array if you need to.
the last two items of an array in Swift
EDIT: first checks that myArray.count >= 2
let myArray2:Array? = myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
Here it is wrapped in a function which takes the array and either returns an array containing the last two or else returns nil if the passed array does not contain at least two items.
func getLastTwo(myArray:[String]) -> [String]? {
return myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
}
With Swift 5, according to your needs, you may choose one of the following patterns in order to get a new array from the last two elements of an array.
suffix(_:)
With Swift, objects that conform to Collection
protocol have a suffix(_:)
method. Array's suffix(_:) has the following declaration:
func suffix(_ maxLength: Int) -> ArraySlice<Element>
Returns a subsequence, up to the given maximum length, containing the final elements of the collection.
Usage:
let array = [1, 2, 3, 4]
let arraySlice = array.suffix(2)
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
Array
's subscript(_:)
As an alternative to suffix(_:)
method, you may use Array
's subscript(_:) subscript:
let array = [1, 2, 3, 4]
let range = array.index(array.endIndex, offsetBy: -2) ..< array.endIndex
//let range = array.index(array.endIndex, offsetBy: -2)... // also works
let arraySlice = array[range]
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
Swift4 solution:
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
let arr1 = threeArray.suffix(from: threeArray.count-2) // ["dos", "tres"]
Other examples to clarify the functionality of Swift's built in function func suffix(from start: Int) -> ArraySlice<Element>
are...
let arr2 = oneArray.suffix(from: 0) // ["uno"]
let arr3 = twoArray.suffix(from: 0) // ["uno", "dos"]
let arr4 = twoArray.suffix(from: 1) // ["dos"]
let arr5 = threeArray.suffix(from: 1) // ["dos", "tres"]
let arr6 = threeArray.suffix(from: 2) // ["tres"]
In Swift 2, you can extend CollectionType
. Here's an example (borrowing from Rob Napier's answer):
extension CollectionType {
func last(count:Int) -> [Self.Generator.Element] {
let selfCount = self.count as! Int
if selfCount <= count - 1 {
return Array(self)
} else {
return Array(self.reverse()[0...count - 1].reverse())
}
}
}
You can use it on any CollectionType
. Here's Array
:
let array = ["uno", "dos", "tres"]
print(array.last(2)) // [dos, tres]
Here's CharacterView
:
let string = "looking"
print(string.characters.last(4)) // [k, i, n, g]
(Note that my example returns an Array in all cases, not the original collection type.)