web-dev-qa-db-fra.com

Dans Swift, quel est le moyen le plus propre d'obtenir les deux derniers éléments d'un tableau?

Existe-t-il un moyen plus propre d'obtenir les deux derniers éléments d'un tableau dans Swift? En général, j'essaie d'éviter cette approche car il est si facile d'être déconnecté des index. (Utilisation de Swift 1.2 pour cet exemple.)

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

J'espérais quelque chose de plus proche de la commodité de Python.

## Python -- very convenient slices
myList = ["uno", "dos", "tres"]
print myList[-2:] # ["dos", "tres"]
23
zekel

myList[-2:]

Oui, j'ai déposé une demande d'amélioration demandant une notation d'index négative, et je vous suggère d'en déposer une également.

Cependant, vous ne devriez pas vous compliquer davantage la tâche. La fonction globale intégrée suffix fait exactement ce que vous recherchez:

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

Le résultat est une tranche, mais vous pouvez la contraindre à un tableau si vous en avez besoin.

43
matt

Avec Swift 5, selon vos besoins, vous pouvez choisir l'un des modèles suivants afin d'obtenir un nouveau tableau à partir des deux derniers éléments d'un tableau.


#1. Utilisation de suffix(_:) d'Array

Avec Swift, les objets conformes au protocole Collection ont une méthode suffix(_:). Le tableau suffix(_:) a la déclaration suivante:

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

Renvoie une sous-séquence, jusqu'à la longueur maximale donnée, contenant les derniers éléments de la collection.

Utilisation:

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

# 2. Utilisation de la fonction subscript(_:) de Array

Comme alternative à la méthode suffix(_:), vous pouvez utiliser l'indice de Arraysubscript(_:) :

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

Dans Swift 2, vous pouvez étendre CollectionType. Voici un exemple (emprunt à la réponse de 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())
        }
    }
}

Vous pouvez l'utiliser sur n'importe quel CollectionType. Voici Array:

let array = ["uno", "dos", "tres"]
print(array.last(2)) // [dos, tres]

Voici CharacterView:

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

(Notez que mon exemple retourne un tableau dans tous les cas, pas le type de collection d'origine.)

6
Aaron Brager

Réponse plus générique ...

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

les deux derniers éléments d'un tableau dans Swift

EDIT: vérifie d'abord que myArray.count> = 2

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

Ici, il est enveloppé dans une fonction qui prend le tableau et retourne un tableau contenant les deux derniers ou bien retourne nil si le tableau passé ne contient pas au moins deux éléments.

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

Je doute que cela vous rendra beaucoup plus heureux, mais le calcul est certainement plus simple:

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

Notez que reverse() est paresseux, donc ce n'est pas particulièrement cher.

1
Rob Napier