在Swift中,获取数组中最后两项的最简洁方法是什么?

zek*_*kel 25 arrays slice swift

是否有更简洁的方法来获取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"]
Run Code Online (Sandbox Code Playgroud)

我希望能有更接近Python的便利性.

## Python -- very convenient slices
myList = ["uno", "dos", "tres"]
print myList[-2:] # ["dos", "tres"]
Run Code Online (Sandbox Code Playgroud)

mat*_*att 44

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"]
Run Code Online (Sandbox Code Playgroud)

结果是切片,但如果需要,可以将其强制转换为数组.

  • 在Swift 2.0中,后缀(MyCoolArray,3)`变成了'MyCoolArray.suffix(3)`我以为我分享了所以没有其他人像我那样吸引掉那么多头发 (25认同)
  • @MartinR我们忘记阅读我的书了.包括我.http://www.apeth.com/swiftBook/ch04.html#_basic_array_properties_and_methods但我不会回答我对其他答案的任何赞美,特别是因为他们建议如何实施`suffix`.这是一个令人惊讶的教育线索. (2认同)

Ima*_*tit 28

使用Swift 4,根据您的需要,您可以选择以下模式之一,以便从数组的最后两个元素中获取新数组.


#1.使用suffix(_:)协议的Collection方法

使用Swift 4,符合suffix(_:)协议的对象有一个suffix(_:)方法.Array方法有以下声明:

func suffix(_ maxLength: Int) -> ArraySlice<Element>
Run Code Online (Sandbox Code Playgroud)

返回一个子序列,直到给定的最大长度,包含集合的最终元素.

用法:

let array = [1, 2, 3, 4]
let arraySlice = array.suffix(2)
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)

#2.使用subscript(_:)下标

func suffix(_ maxLength: Int) -> ArraySlice<Element>
Run Code Online (Sandbox Code Playgroud)

#3.使用您自己的suffix(_:)扩展方法

let array = [1, 2, 3, 4]
let arraySlice = array.suffix(2)
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
Run Code Online (Sandbox Code Playgroud)

用法:

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]
Run Code Online (Sandbox Code Playgroud)
func suffix(_ maxLength: Int) -> ArraySlice<Element>
Run Code Online (Sandbox Code Playgroud)


Aar*_*ger 6

在Swift 2中,您可以扩展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())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以在任何地方使用它CollectionType.这是Array:

let array = ["uno", "dos", "tres"]
print(array.last(2)) // [dos, tres]
Run Code Online (Sandbox Code Playgroud)

这是CharacterView:

let string = "looking"
print(string.characters.last(4)) // [k, i, n, g]
Run Code Online (Sandbox Code Playgroud)

(请注意,我的示例在所有情况下都返回一个数组,而不是原始集合类型.)

  • "我的例子在所有情况下都会返回一个数组"但这似乎完全合理; "地图"的行为方式与IIRC相同.如果需要,你总是可以回到任何它. (2认同)

moh*_*sen 5

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"]
Run Code Online (Sandbox Code Playgroud)

结果是一个切片,但如果需要,您可以将其强制转换为一个数组。