Comment utiliser swift flatMap filtrer les options à partir d'un tableau
Je suis un peu confus autour de flatMap (ajouté Swift 1.2)
Dire que j'ai un tableau d'une option de type par exemple
let possibles:[Int?] = [nil, 1, 2, 3, nil, nil, 4, 5]
Dans Swift 1.1 je ferais un filtre suivie par une carte comme ceci:
let filtermap = possibles.filter({ return $0 != nil }).map({ return $0! })
// filtermap = [1, 2, 3, 4, 5]
J'ai essayé de faire cela à l'aide de flatMap un couple de façons:
var flatmap1 = possibles.flatMap({
return $0 == nil ? [] : [$0!]
})
et
var flatmap2:[Int] = possibles.flatMap({
if let exercise = $0 { return [exercise] }
return []
})
Je préfère la dernière approche (parce que je n'ai pas à forcer une déballer $0!
... je suis terrifié et d'éviter à tout prix), sauf que j'ai besoin de spécifier le type du Tableau.
Est-il une alternative à l'écart qui détermine le type de contexte, mais qui n'ont pas forcé déballer?
- Vous signifiait probablement Swift 1.2 vs 1.1, il n'y a pas de Swift 1.3 (ou ai-je raté quelque chose?)
- Opps, oui pense que j'ai eu Xcode 6.3 sur mon esprit (...) mise à jour de question - merci!
- Bien que vous pouvez utiliser
flatMap { $0 }
pour supprimer nils, la vraie question est de savoir si vous. Si vous ne faites pas attention,flatMap
peut conduire à des bugs, donc je vous recommande d'utiliser removeNils à la place.
Vous devez vous connecter pour publier un commentaire.
Depuis Swift 4.1 vous pouvez utiliser compactMap:
(Swift 4.1 remplacé certaines surcharges de flatMap avec compactmap.
Si vous êtes intéressé par plus de détails sur cette puis voir, par exemple:
https://useyourloaf.com/blog/replacing-flatmap-with-compactmap/
)
Avec Swift 2 b1, vous pouvez simplement faire
Pour les versions antérieures, vous pouvez shim ce avec l'extension suivante:
Une mise en garde (qui est également vrai pour Swift 2) est ce que vous pourriez devez le spécifier explicitement le type de la valeur de retour de la transformation:
Pour plus d'info, voir http://airspeedvelocity.net/2015/07/23/changes-to-the-swift-standard-library-in-2-0-betas-2-5/
J'aime toujours la première solution, qui ne crée qu'un seul intermédiaire
tableau. Il peut légèrement plus compacte être écrit comme
Mais
flatMap()
sans annotation de type et sans forcédéballage est possible:
L'extérieur
flatMap
est la méthode de la baieet l'intérieur
flatMap
est la fonctionIci est une simple comparaison des performances (compilé en mode Release).
Il montre que la première méthode est plus rapide, environ d'un facteur
de 10:
possibles.flatmap{ $0 }
. Voir les docs:public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T]
Flatmap retourne unArray
contenant le non-néant les résultats de la cartographie de l'transform
surself
.Vous pouvez utiliser
reduce
:Vous êtes encore un peu de déclarer le type, mais c'est un peu moins gênant.
Puisque c'est quelque chose que je semble faire beaucoup de choses, je suis d'explorer une fonction générique pour ce faire.
J'ai essayé d'ajouter une extension à la Matrice afin que je puisse faire quelque chose comme
possibles.unwraped
mais je ne pouvais pas comprendre comment faire une extension sur un Tableau. Au lieu personnalisé opérateur -- la partie la plus difficile ici est d'essayer de comprendre quel opérateur choisir. En fin de compte j'ai choisi>!
pour montrer que la matrice est filtré>
et puis déballé!
.Liées à la question. Si vous postulez
flatMap
à un tableau facultatif, n'oubliez pas d'option ou de la force de déballer votre tableau sinon il va appelerflatMap
surOptional
et non des objets conformes àSequence
protocole. J'ai fait cette erreur une fois, E. g. si vous voulez supprimer des chaînes vides: