Dans Swift, existe-t-il un moyen astucieux d'utiliser les méthodes d'ordre supérieur sur Array pour renvoyer les 5 premiers objets? La manière de procéder obj-c consistait à enregistrer un index et à effectuer une boucle dans l’index d’incrémentation du tableau jusqu’à ce qu'il soit 5 et à renvoyer le nouveau tableau. Existe-t-il un moyen de faire cela avec filter
, map
ou reduce
?
De loin, le moyen le plus simple d’obtenir les N premiers éléments d’un tableau Swift consiste à utiliser prefix(maxLength: Int)
:
let someArray = [1, 2, 3, 4, 5, 6, 7]
let first5 = someArray.prefix(5) // 1, 2, 3, 4, 5
Cela a l'avantage d'être sécurisé. Si le nombre que vous passez à prefix
est supérieur au nombre de tableaux, il renvoie simplement le tableau entier.
REMARQUE: comme indiqué dans les commentaires, Array.prefix
renvoie en fait une ArraySlice
, pas une Array
. Dans la plupart des cas, cela ne devrait pas faire de différence, mais si vous devez affecter le résultat à un type Array
ou le transmettre à une méthode qui attend un paramètre Array
, vous devrez forcer le résultat dans un type Array
: let first5 = Array(someArray.prefix(5))
Update: Il est maintenant possible d'utiliser prefix
pour obtenir les n premiers éléments d'un tableau. Vérifiez la réponse de @ mluisbrown pour une explication sur l’utilisation du préfixe.
Réponse originale: Vous pouvez le faire facilement sans filter
, map
ou reduce
en renvoyant simplement une plage de votre tableau
var wholeArray = [1, 2, 3, 4, 5, 6]
var n = 5
var firstFive = wholeArray[0..<n] // 1,2,3,4,5
Avec Swift 4.2, en fonction de vos besoins, vous pouvez choisir l’un des les 6 codes suivants du terrain de jeu pour résoudre votre problème.
subscript(_:)
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array[..<5]
//let arraySlice = array[0..<5] // also works
//let arraySlice = array[0...4] // also works
//let arraySlice = array[...4] // also works
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
prefix(_:)
Complexité: O(1) si la collection est conforme à RandomAccessCollection
; sinon, O (k), où k est le nombre d'éléments à sélectionner depuis le début de la collection.
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
Apple déclare pour prefix(_:)
:
Si la longueur maximale dépasse le nombre d'éléments de la collection, le résultat contient tous les éléments de la collection.
prefix(upTo:)
Complexité: O (1)
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(upTo: 5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
Apple déclare pour prefix(upTo:)
:
L'utilisation de la méthode
prefix(upTo:)
équivaut à utiliser une plage semi-ouverte partielle comme indice de la collection. La notation en indice est préférable àprefix(upTo:)
.
prefix(through:)
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(through: 4)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
removeSubrange(_:)
Complexité: O (n), où n est la longueur de la collection.
var array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
array.removeSubrange(5...)
print(array) // prints: ["A", "B", "C", "D", "E"]
dropLast(_:)
Complexité: O (n), où n est le nombre d'éléments à supprimer.
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let distance = array.distance(from: 5, to: array.endIndex)
let arraySlice = array.dropLast(distance)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
let a: [Int] = [0, 0, 1, 1, 2, 2, 3, 3, 4]
let b: [Int] = Array(a.prefix(5))
// result is [0, 0, 1, 1, 2]
Pour obtenir les 5 premiers éléments d'un tableau, il suffit de couper le tableau en question. Dans Swift, vous le faites comme ceci: array[0..<5]
.
Pour rendre la sélection des N premiers éléments d’un tableau un peu plus fonctionnelle et généralisable, vous pouvez créer une méthode d’extension pour le faire. Par exemple:
extension Array {
func takeElements(var elementCount: Int) -> Array {
if (elementCount > count) {
elementCount = count
}
return Array(self[0..<elementCount])
}
}
Swift 4
Une solution différente:
Une solution en ligne facile qui ne plantera pas si votre tableau est trop court
[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 3 ? $0.element : nil }
Mais fonctionne bien avec cela.
[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 1000 ? $0.element : nil }
Habituellement, cela planterait si vous faisiez ceci:
[0,1,2,3,4,5].prefix(upTo: 1000) // THIS CRASHES
[0,1,2,3,4,5].prefix(1000) // THIS DOESNT
J'ai légèrement modifié la réponse de Markus pour la mettre à jour pour la dernière version de Swift, car var
dans la déclaration de votre méthode n'est plus pris en charge:
extension Array {
func takeElements(elementCount: Int) -> Array {
if (elementCount > count) {
return Array(self[0..<count])
}
return Array(self[0..<elementCount])
}
}
Mise à jour pour Swift 4:
[0,1,2,3,4,5].enumerated().compactMap{ $0 < 10000 ? $1 : nil }
Pour Swift 3:
[0,1,2,3,4,5].enumerated().flatMap{ $0 < 10000 ? $1 : nil }
Pour un tableau d'objets, vous pouvez créer une extension à partir de la séquence.
extension Sequence {
func limit(_ max: Int) -> [Element] {
return self.enumerated()
.filter { $0.offset < max }
.map { $0.element }
}
}
Usage:
struct Apple {}
let apples: [Apple] = [Apple(), Apple(), Apple()]
let limitTwoApples = apples.limit(2)
// limitTwoApples: [Apple(), Apple()]
Plain & Simple
extension Array {
func first(elementCount: Int) -> Array {
let min = Swift.min(elementCount, count)
return Array(self[0..<min])
}
}
Swift 4
Pour obtenir les N premiers éléments d'un tableau Swift, vous pouvez utiliser prefix(_ maxLength: Int)
:
Array(largeArray.prefix(5))
Swift 4 avec sauvegarde de types de tableaux
extension Array {
func take(_ elementsCount: Int) -> [Element] {
let min = Swift.min(elementsCount, count)
return Array(self[0..<min])
}
}