Existe-t-il un moyen de travailler avec des plages inversées dans Swift?
Par exemple:
for i in 5...1 {
// do something
}
est une boucle infinie.
Dans les nouvelles versions de Swift, ce code se compile, mais au moment de l'exécution donne l'erreur:
Erreur fatale: impossible de former une plage avec UpperBound <lowerBound
Je sais que je peux utiliser à la 1..5
place, calculer j = 6 - i
et utiliser j
comme index. Je me demandais juste s'il y avait quelque chose de plus lisible?
Réponses:
Mise à jour pour le dernier Swift 3 (fonctionne toujours dans Swift 4)
Vous pouvez utiliser la
reversed()
méthode sur une plageOu
stride(from:through:by:)
méthodestide(from:to:by:)
est similaire mais exclut la dernière valeurMise à jour pour le dernier Swift 2
Tout d'abord, les extensions de protocole modifient leur
reverse
utilisation:for i in (1...5).reverse() { print(i) } // 5 4 3 2 1
Stride a été retravaillé dans Xcode 7 Beta 6. La nouvelle utilisation est:
Cela fonctionne également pour
Doubles
:Méfiez-vous de la virgule flottante compare ici pour les limites.
Edition antérieure pour Swift 1.2 : à partir de Xcode 6 Beta 4, par et ReverseRange n'existent plus: [
Si vous cherchez simplement à inverser une plage, la fonction d' inversion est tout ce dont vous avez besoin:
Tel que publié par 0x7fffffff, il existe une nouvelle construction de pas qui peut être utilisée pour itérer et incrémenter par des entiers arbitraires. Apple a également déclaré que le support en virgule flottante était à venir.
Tiré de sa réponse:
la source
(1...5).reverse()
(comme appel de fonction), veuillez mettre à jour votre réponse. (Comme il ne s'agit que de deux caractères, je n'ai pas pu modifier votre message.)(1...5).reversed()
. De plus, l'exemple de.stride()
ne fonctionne pas et a besoin de la fonction gratuite à lastride(from:to:by:)
place.stride
code de swift 3 est légèrement incorrect. pour inclure le numéro 1, vous devez utiliserthrough
opposé àto
comme ceci:for i in stride(from:5,through:1,by:-1) { print(i) }
reversed
a une complexité de O (1) car il enveloppe simplement la collection d'origine et ne nécessite pas d'itération pour la construire.Il y a quelque chose de troublant dans l'asymétrie de ceci:
... par opposition à ceci:
Cela signifie que chaque fois que je veux faire une gamme inversée, je dois me rappeler de mettre les parenthèses, plus je dois écrire cela
.reverse()
à la fin, en sortant comme un pouce endolori. C'est vraiment moche par rapport aux boucles for de style C, qui sont symétriques comptant et décomptant. J'ai donc tendance à utiliser plutôt le style C pour les boucles. Mais dans Swift 2.2, les boucles for de style C disparaissent! J'ai donc dû me dépêcher de remplacer toutes mes boucles for décrémentantes de style C par cette conception laide.reverse()
- en me demandant tout le temps, pourquoi diable n'y a-t-il pas d'opérateur de plage inversée?Mais attendez! C'est Swift - nous sommes autorisés à définir nos propres opérateurs !! Et c'est parti:
Alors maintenant, j'ai le droit de dire:
Ce ne couvre que le plus de cas commun qui se produit dans mon code, mais il est loin le cas le plus commun, il est donc tout ce que je besoin à l' heure actuelle.
J'ai eu une sorte de crise interne avec l'opérateur. J'aurais aimé utiliser
>..
, comme étant l'inverse de..<
, mais ce n'est pas légal: vous ne pouvez pas utiliser un point après un non-point, il apparaît. J'ai réfléchi,..>
mais j'ai décidé que c'était trop difficile à distinguer..<
. Ce>>>
qui est bien, c'est qu'il vous crie dessus: " jusqu'à !" (Bien sûr, vous êtes libre de trouver un autre opérateur. Mais mon conseil est le suivant: pour la super symétrie, définissez<<<
pour faire ce qui..<
fait, et maintenant vous avez<<<
et>>>
qui sont symétriques et faciles à taper.)Version Swift 3 (Xcode 8 seed 6):
Version Swift 4 (Xcode 9 beta 3):
Version Swift 4.2 (Xcode 10 beta 1):
Version Swift 5 (Xcode 10.2.1):
la source
>>>
opérateur est vraiment cool! J'espère que les designers de Swift prêtent attention à des choses comme ça, parce que resterreverse()
à la fin des expressions entre parenthèses est bizarre. Il n'y a aucune raison pour laquelle ils ne pourraient pas traiter5>..0
automatiquement les plages, car leForwardIndexType
protocole fournit undistanceTo()
opérateur parfaitement raisonnable qui peut être utilisé pour déterminer si la foulée doit être positive ou négative.Il semble que les réponses à cette question ont un peu changé au fur et à mesure que nous progressons dans les bêtas. Depuis la version bêta 4, la
by()
fonction et leReversedRange
type ont été supprimés du langage. Si vous cherchez à créer une plage inversée, vos options sont désormais les suivantes:1: Créez une plage avant, puis utilisez la
reverse()
fonction pour l'inverser.2: Utilisez les nouvelles
stride()
fonctions qui ont été ajoutées dans la version bêta 4, qui comprend des fonctions pour spécifier les index de début et de fin, ainsi que la quantité d'itération.Notez que j'ai également inclus le nouvel opérateur de plage exclusif dans cet article.
..
a été remplacé par..<
.Edit: À partir des notes de version de Xcode 6 beta 5 , Apple a ajouté la suggestion suivante pour gérer cela:
Voici un exemple.
la source
lazy(0....5).reverse()
et je ne vois pas les notes de version bêta 5. Connaissez-vous d'autres discussions sur ce sujet? De plus, pour info, les nombres à l'intérieur de cettefor
boucle sont inversés dans votre exemple.// 0, 1, 2, 3, 4, 5
mais il devrait en fait être inversé. Le commentaire est trompeur.Xcode 7, bêta 2:
la source
Swift 3, 4+ : vous pouvez le faire comme ceci:
résultat : 10, 9, 8 ... 0
Vous pouvez le personnaliser comme vous le souhaitez. Pour plus d'informations, lisez la
func sequence<T>
référencela source
Cela pourrait être une autre façon de procéder.
la source
La fonction Reverse () est utilisée pour le nombre inverse.
Var n: Int // Entrez le nombre
Pour i en 1 ... n.reverse () {Print (i)}
la source