web-dev-qa-db-fra.com

Comment retourner les 5 premiers objets de Array dans Swift?

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?

108
bogen

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))

278
mluisbrown

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
91
Christian

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.


#1. Utilisation de l'indice 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"]

# 2. Utilisation de la méthode 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.


# 3. Utilisation de la méthode 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:).


# 4. Utilisation de la méthode 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"]

# 5. Utilisation de la méthode 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"]

# 6. Utilisation de la méthode 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"]
28
Imanou Petit
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]
25
neoneye

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])
    }
}
14
Markus

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
13
David Rees

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])
    }
}
4
Antoine

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 }
2
mkkrolik

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()]
1
Leo Valentim

Plain & Simple

extension Array {
    func first(elementCount: Int) -> Array {
          let min = Swift.min(elementCount, count)
          return Array(self[0..<min])
    }
}
1
Abhishek Bedi

Swift 4

Pour obtenir les N premiers éléments d'un tableau Swift, vous pouvez utiliser prefix(_ maxLength: Int):

Array(largeArray.prefix(5))
0
quemeful

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])
    }
}
0
comm1x