在 Swift 中,获取数组中最后两项的最简洁方法是什么?
In Swift, what's the cleanest way to get the last two items in an Array?
有没有更简洁的方法来获取 Swift 中数组的最后两项?一般来说,我尽量避免使用这种方法,因为它很容易与索引相差甚远。 (此示例使用 Swift 1.2。)
// Swift -- slices are kind of a hassle?
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
func getLastTwo(array: [String]) -> [String] {
if array.count <= 1 {
return array
} else {
let slice: ArraySlice<String> = array[array.endIndex-2..<array.endIndex]
var lastTwo: Array<String> = Array(slice)
return lastTwo
}
}
getLastTwo(oneArray) // ["uno"]
getLastTwo(twoArray) // ["uno", "dos"]
getLastTwo(threeArray) // ["dos", "tres"]
我希望有一些更接近 Python 的便利。
## Python -- very convenient slices
myList = ["uno", "dos", "tres"]
print myList[-2:] # ["dos", "tres"]
我怀疑它会让你更快乐,但数学肯定更简单:
func getLastTwo(array: [String]) -> [String] {
if array.count <= 1 {
return array
} else {
return array.reverse()[0...1].reverse()
}
}
请注意 reverse()
是懒惰的,所以这不是特别昂贵。
更通用的答案...
let a1 = [1,2,3,4,5]
let a2 = ["1","2","3","4","5"]
func getLast<T>(array: [T], count: Int) -> [T] {
if count >= array.count {
return array
}
let first = array.count - count
return Array(array[first..<first+count])
}
getLast(a1, count: 2) // [4, 5]
getLast(a2, count: 3) // ["3", "4", "5"]
在Swift2中,可以扩展CollectionType
。这是一个示例(借用 Rob Napier 的回答):
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())
}
}
}
您可以在任何 CollectionType
上使用它。这里是 Array
:
let array = ["uno", "dos", "tres"]
print(array.last(2)) // [dos, tres]
这里是CharacterView
:
let string = "looking"
print(string.characters.last(4)) // [k, i, n, g]
(请注意,我的示例 returns 在所有情况下都是数组,而不是原始集合类型。)
the last two items of an array in Swift
编辑:首先检查 myArray.count >= 2
let myArray2:Array? = myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
这里它被包装在一个函数中,该函数接受数组和 returns 一个包含最后两项的数组,否则 returns nil 如果传递的数组不包含至少两个项目。
func getLastTwo(myArray:[String]) -> [String]? {
return myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
}
myList[-2:]
是的,我提交了一个增强请求,要求使用负索引符号,我建议你也提交一个。
但是,你不应该让自己变得更难。内置的全局 suffix
函数完全符合您的要求:
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
let arr1 = suffix(oneArray,2) // ["uno"]
let arr2 = suffix(twoArray,2) // ["uno", "dos"]
let arr3 = suffix(threeArray,2) // ["dos", "tres"]
结果是一个切片,但如果需要,您可以将其强制转换为数组。
与Swift 5,根据您的需要,您可以选择以下模式之一,以便从数组的最后两个元素得到一个新数组。
#1。使用数组的 suffix(_:)
使用Swift,符合Collection
协议的对象有一个suffix(_:)
方法。数组的 suffix(_:)
具有以下声明:
func suffix(_ maxLength: Int) -> ArraySlice<Element>
Returns a subsequence, up to the given maximum length, containing the final elements of the collection.
用法:
let array = [1, 2, 3, 4]
let arraySlice = array.suffix(2)
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
#2。使用 Array
的 subscript(_:)
作为 suffix(_:)
方法的替代方法,您可以使用 Array
的 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]
let items = [0, 2, 5, 3, 7, 6, 9, 10]
let count = items.count
let last2 = items[count - 2 ..< count] // [9, 10]
Swift4 解法:
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
let arr1 = threeArray.suffix(from: threeArray.count-2) // ["dos", "tres"]
阐明 Swift 的内置函数 func suffix(from start: Int) -> ArraySlice<Element>
功能的其他示例是...
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 5 你可以使用后缀从最后一个获取对象,使用前缀从第一个获取对象,这里是一个例子:
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"]
结果是一个切片,但如果需要,您可以将其强制转换为数组。
有没有更简洁的方法来获取 Swift 中数组的最后两项?一般来说,我尽量避免使用这种方法,因为它很容易与索引相差甚远。 (此示例使用 Swift 1.2。)
// Swift -- slices are kind of a hassle?
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
func getLastTwo(array: [String]) -> [String] {
if array.count <= 1 {
return array
} else {
let slice: ArraySlice<String> = array[array.endIndex-2..<array.endIndex]
var lastTwo: Array<String> = Array(slice)
return lastTwo
}
}
getLastTwo(oneArray) // ["uno"]
getLastTwo(twoArray) // ["uno", "dos"]
getLastTwo(threeArray) // ["dos", "tres"]
我希望有一些更接近 Python 的便利。
## Python -- very convenient slices
myList = ["uno", "dos", "tres"]
print myList[-2:] # ["dos", "tres"]
我怀疑它会让你更快乐,但数学肯定更简单:
func getLastTwo(array: [String]) -> [String] {
if array.count <= 1 {
return array
} else {
return array.reverse()[0...1].reverse()
}
}
请注意 reverse()
是懒惰的,所以这不是特别昂贵。
更通用的答案...
let a1 = [1,2,3,4,5]
let a2 = ["1","2","3","4","5"]
func getLast<T>(array: [T], count: Int) -> [T] {
if count >= array.count {
return array
}
let first = array.count - count
return Array(array[first..<first+count])
}
getLast(a1, count: 2) // [4, 5]
getLast(a2, count: 3) // ["3", "4", "5"]
在Swift2中,可以扩展CollectionType
。这是一个示例(借用 Rob Napier 的回答):
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())
}
}
}
您可以在任何 CollectionType
上使用它。这里是 Array
:
let array = ["uno", "dos", "tres"]
print(array.last(2)) // [dos, tres]
这里是CharacterView
:
let string = "looking"
print(string.characters.last(4)) // [k, i, n, g]
(请注意,我的示例 returns 在所有情况下都是数组,而不是原始集合类型。)
the last two items of an array in Swift
编辑:首先检查 myArray.count >= 2
let myArray2:Array? = myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
这里它被包装在一个函数中,该函数接受数组和 returns 一个包含最后两项的数组,否则 returns nil 如果传递的数组不包含至少两个项目。
func getLastTwo(myArray:[String]) -> [String]? {
return myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
}
myList[-2:]
是的,我提交了一个增强请求,要求使用负索引符号,我建议你也提交一个。
但是,你不应该让自己变得更难。内置的全局 suffix
函数完全符合您的要求:
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
let arr1 = suffix(oneArray,2) // ["uno"]
let arr2 = suffix(twoArray,2) // ["uno", "dos"]
let arr3 = suffix(threeArray,2) // ["dos", "tres"]
结果是一个切片,但如果需要,您可以将其强制转换为数组。
与Swift 5,根据您的需要,您可以选择以下模式之一,以便从数组的最后两个元素得到一个新数组。
#1。使用数组的 suffix(_:)
使用Swift,符合Collection
协议的对象有一个suffix(_:)
方法。数组的 suffix(_:)
具有以下声明:
func suffix(_ maxLength: Int) -> ArraySlice<Element>
Returns a subsequence, up to the given maximum length, containing the final elements of the collection.
用法:
let array = [1, 2, 3, 4]
let arraySlice = array.suffix(2)
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
#2。使用 Array
的 subscript(_:)
作为 suffix(_:)
方法的替代方法,您可以使用 Array
的 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]
let items = [0, 2, 5, 3, 7, 6, 9, 10]
let count = items.count
let last2 = items[count - 2 ..< count] // [9, 10]
Swift4 解法:
let oneArray = ["uno"]
let twoArray = ["uno", "dos"]
let threeArray = ["uno", "dos", "tres"]
let arr1 = threeArray.suffix(from: threeArray.count-2) // ["dos", "tres"]
阐明 Swift 的内置函数 func suffix(from start: Int) -> ArraySlice<Element>
功能的其他示例是...
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 5 你可以使用后缀从最后一个获取对象,使用前缀从第一个获取对象,这里是一个例子:
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"]
结果是一个切片,但如果需要,您可以将其强制转换为数组。