Ordre supérieur personnalisé
Fait partie de la section Logique et Flux du Journey Swift de Coddy — leçon 42 sur 56.
Maintenant, vous pouvez écrire vos propres fonctions d'ordre supérieur et elles s'intégreront parfaitement aux côtés de map et filter. La structure est toujours la même : prendre une closure en paramètre, l'appeler à l'intérieur de la boucle, retourner le résultat.
extension Array {
func myMap<T>(_ transform: (Element) -> T) -> [T] {
var result: [T] = []
for item in self {
result.append(transform(item))
}
return result
}
}
[1, 2, 3].myMap { $0 * 10 } // [10, 20, 30]Si les extensions vous semblent excessives, écrivez plutôt une fonction libre, l'idée est la même :
func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
var n = 0
for item in items where predicate(item) {
n += 1
}
return n
}Une fois que vous pouvez transmettre des fermetures (closures), la bibliothèque standard cesse de ressembler à de la magie et commence à ressembler à un ensemble de modèles que vous pourriez écrire vous-même.
Défi
MoyenÉcrivez une fonction libre partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) qui parcourt le tableau une seule fois et retourne un tuple (matched, rest) : les éléments qui ont satisfait le prédicat, et le reste, tous deux dans l'ordre d'origine.
Lisez deux lignes : un entier min, puis une liste d'entiers séparés par des virgules. Utilisez votre fonction partition avec un prédicat qui vérifie n > min. Affichez :
matched: <...>rest: <...>
Chaque liste jointe avec , (ou vide s'il n'y a rien à afficher).
Pour l'entrée 5 / 2,7,3,8,5, la sortie est :
matched: 7,8
rest: 2,3,5Aide-mémoire
Les fonctions d'ordre supérieur suivent un modèle cohérent : accepter une closure, l'appeler dans une boucle, retourner le résultat.
En tant qu'extension :
extension Array {
func myMap<T>(_ transform: (Element) -> T) -> [T] {
var result: [T] = []
for item in self {
result.append(transform(item))
}
return result
}
}
[1, 2, 3].myMap { $0 * 10 } // [10, 20, 30]En tant que fonction libre :
func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
var n = 0
for item in items where predicate(item) {
n += 1
}
return n
}Une fonction partition retournant un tuple d'éléments correspondants et non correspondants :
func partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) {
var matched: [Int] = []
var rest: [Int] = []
for item in items {
if predicate(item) { matched.append(item) }
else { rest.append(item) }
}
return (matched, rest)
}Essayez vous-même
let min = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }
// TODO: partition(_:by:) -> ([Int], [Int]); afficher les éléments correspondants et le reste
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Logique et Flux
1Les chaînes de caractères en profondeur
Comptage et indicesCasse et nettoyageRecherche dans les chaînesDécoupage et jointureRemplacement de sous-chaînesRécapitulatif - Vérification du nom d'utilisateur4Ensembles
Création d'ensemblesUnion et intersectionSoustraction et différence symétriqueSous-ensemble et sur-ensembleRécapitulatif - Filtre de tags7Projet - Suivi d'habitudes
Aperçu du projetMarquer comme terminé10Projet - Moteur de quiz
Présentation du projetPoser des questions2Intervalles et Pas
Fermé vs Semi-ouvertLe PasMéthodes d'intervalleIntervalles dans un SwitchRécapitulatif - Grille de calendrier5Fonctions d'ordre supérieur, Partie 1
MapFilterReduceChaînage de map, filter, reduceRécapitulatif - Statistiques de mots8Closures
Les bases des closuresClosures finalesCapture de valeursRetourner des closuresOrdre supérieur personnaliséRécapitulatif - Pipeline Builder