web-dev-qa-db-ja.com

Swiftでは、配列の最後の2つのアイテムを取得する最もクリーンな方法は何ですか?

Swiftで配列の最後の2つのアイテムを取得するよりクリーンな方法はありますか?一般に、インデックスを1つずつずらすのは簡単なので、このアプローチは避けようとします。 (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"]
23
zekel

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"]

結果はスライスですが、必要に応じて配列に強制できます。

43
matt

Swift 5、必要に応じて、配列の最後の2つの要素から新しい配列を取得するために、次のパターンのいずれかを選択できます。


#1。配列のsuffix(_:)を使用する

Swiftでは、Collectionプロトコルに準拠するオブジェクトにはsuffix(_:)メソッドがあります。配列の suffix(_:) には次の宣言があります。

_func suffix(_ maxLength: Int) -> ArraySlice<Element>
_

コレクションの最終要素を含む、指定された最大長までのサブシーケンスを返します。

使用法:

_let array = [1, 2, 3, 4]
let arraySlice = array.suffix(2)
let newArray = Array(arraySlice)
print(newArray) // prints: [3, 4]
_

#2。 Arraysubscript(_:)を使用する

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]
_
26
Imanou Petit

Swift 2)では、CollectionTypeを拡張できます。以下に例を示します(ロブネイピアの回答から引用)。

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]

(私の例は、元のコレクション型ではなく、すべての場合に配列を返すことに注意してください。)

6
Aaron Brager

より一般的な答え...

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"]
3
zrzka
let items = [0, 2, 5, 3, 7, 6, 9, 10]
let count = items.count
let last2 = items[count - 2 ..< count] // [9, 10]
2
Adrian Mannella

swiftの配列の最後の2つの項目

編集:最初にmyArray.count> = 2であることを確認します

let myArray2:Array? = myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil

ここでは、配列を取り、最後の2つを含む配列を返すか、渡された配列に少なくとも2つの項目が含まれていない場合はnilを返す関数にラップされています。

func getLastTwo(myArray:[String]) -> [String]? {
        return myArray.count >= 2 ? [myArray[myArray.count-2], myArray[myArray.count-1]] : nil
    }
2
simons

そんなに幸せになるとは思いませんが、数学は確かに簡単です:

_func getLastTwo(array: [String]) -> [String] {
    if array.count <= 1 {
        return array
    } else {
        return array.reverse()[0...1].reverse()
    }
}
_

reverse()は遅延であるため、これは特に高価ではありません。

1
Rob Napier