web-dev-qa-db-fra.com

Changer d’instruction dans Swift

J'apprends la syntaxe de Swift et je me demande bien pourquoi le code suivant ne fonctionne pas comme prévu:

for i in 1...100{

    switch (i){
    case 1:
        Int(i%3) == 0
        println("Fizz")
    case 2:
        Int(i%5) == 0
        println("Buzz")
    default:
        println("\(i)")
    }  
}

Je veux imprimer Fizz à chaque fois qu'un nombre est divisible par 3 (3, 6, 9, 12, etc.) et imprimer Buzz à chaque fois qu'il est divisible par 5. Quelle pièce du puzzle manque?

Remarque: je l'ai résolu en utilisant les éléments suivants:

for ( var i = 0; i < 101; i++){

    if (Int(i%3) == 0){
        println("Fizz")
    }   else if (Int(i%5) == 0){
        println("Buzz")
    }   else {
        println("\(i)")
    }   
}

Je veux savoir comment résoudre ce problème en utilisant Switch. Merci.

35
Evgeniy Kleban

Les règles habituelles pour le jeu FizzBuzz sont de remplacer chaque multiple de 3 par "Fizz", chaque multiple de 5 par "Buzz", et chaque multiple de 3 et 5 par "FizzBuzz".

Cela peut être fait avec une instruction switch sur le Tuple (i % 3, i % 5). Notez que _ signifie "toute valeur":

for i in 1 ... 100 {
    switch (i % 3, i % 5) {
    case (0, 0):
        print("FizzBuzz")
    case (0, _):
        print("Fizz")
    case (_, 0):
        print("Buzz")
    default:
        print(i)
    }
}
101
Martin R

Basculez les instructions dans Swift supporte les liaisons de valeurs).
Cela vous permet d’affecter une valeur correspondant à une certaine condition (évaluée via la clause where.) À une variable temporaire (x & y ici):

for i in 1...100 {
    switch (i){
    case let x where x%3 == 0:
        println("Fizz")
    case let y where y%5 == 0:
        println("Buzz")
    default:
        println("\(i)")
    }
}

Vous pouvez également utiliser la valeur de temp attribuée dans le corps du cas.

Mise à jour:
Matt Gibson précise dans les commentaires que vous pouvez omettre l’affectation à un var temporaire si vous n’allez pas l’utiliser dans le corps de l’affaire.
Une version plus concise du code ci-dessus serait donc:

for i in 1...100 {
    switch (i){
    case _ where i%3 == 0:
        println("Fizz")
    case _ where i%5 == 0:
        println("Buzz")
    default:
        println("\(i)")
    }
}

Remarque secondaire: vos deux exemples de code sont légèrement différents (le premier utilise la plage 0-100 en tant qu'entrée, le second utilise la valeur 1-100). Mon échantillon est basé sur votre premier extrait de code.

20
Thomas Zoechling

Ceci est une réponse plus générale pour les personnes qui viennent ici veulent juste savoir comment utiliser l'instruction switch dans Swift.

Utilisation générale

switch someValue {
case valueOne:
    // executable code
case valueTwo:
    // executable code
default:
    // executable code
}

Exemple

let someValue = "horse"

switch someValue {
case "horse":
    print("eats grass")
case "wolf":
    print("eats meat")
default:
    print("no match")
}

Notes:

  • Aucune instruction break n'est nécessaire. C'est le comportement par défaut. Swift switch les cas ne tombent pas.). Si vous voulez qu'ils tombent dans le code dans le cas suivant, vous devez utiliser explicitement le fallthrough. mot-clé.
  • Chaque cas doit inclure du code exécutable. Si vous souhaitez ignorer un cas, vous pouvez ajouter une seule instruction break.
  • Les cas doivent être exhaustifs. C'est-à-dire qu'ils doivent couvrir toutes les valeurs possibles. S'il n'est pas possible d'inclure suffisamment d'instructions case, une instruction default peut être incluse en dernier pour intercepter toute autre valeur.

L'instruction Swift switch est très flexible. Les sections suivantes proposent d'autres manières de l'utiliser.

Faire correspondre plusieurs valeurs

Vous pouvez faire correspondre plusieurs valeurs dans un seul cas si vous utilisez séparer les valeurs par des virgules. Ceci s'appelle un cas composé .

let someValue = "e"

switch someValue {
case "a", "b", "c":
    // executable code
case "d", "e":
    // executable code
default:
    // executable code
}

Vous pouvez également faire correspondre des intervalles entiers .

let someValue = 4

switch someValue {
case 0..<10:
    // executable code
case 10...100:
    // executable code
default:
    // executable code
}

Vous pouvez même utiliser des tuples . Cet exemple est adapté de documentation .

let aPoint = (1, 1)

switch aPoint {
case (0, 0):
    // only catches an exact match for first and second
case (_, 0):
    // any first, exact second
case (-2...2, -2...2):
    // range for first and second
default:
    // catches anything else
}

Liens de valeur

Parfois, vous pouvez créer une constante temporaire ou une variable à partir de la valeur switch. Vous pouvez le faire juste après l'instruction case. Partout où une liaison de valeur est utilisée, elle correspond à n'importe quelle valeur. Ceci est similaire à l'utilisation de _ dans l'exemple de tuple ci-dessus. Les deux exemples suivants sont modifiés à partir de documentation .

let anotherPoint = (2, 0)

switch anotherPoint {
case (let x, 0):
    // can use x here
case (0, let y):
    // can use y here
case let (x, y):
    // can use x or y here, matches anything so no "default" case is necessary
}

Vous pouvez affiner davantage la correspondance en utilisant le mot clé where.

let yetAnotherPoint = (1, -1)

switch yetAnotherPoint {
case let (x, y) where x == y:
    // executable code
case let (x, y) where x == -y:
    // executable code
case let (x, y):
    // executable code
}

Une étude plus approfondie

  • Cette réponse devait être une référence rapide. Veuillez lire l'intégralité de la documentation pour plus d'informations. Ce n'est pas difficile à comprendre.
13
Suragch

Voici comment cela peut être fait

var i = 0

switch i  {

case i where i % 5 == 0 && i % 3 == 0: print(" Fizz Buzz")
case i where i % 3 == 0 : print("Fizz")
case i where i % 5 == 0 : print("Buzz")
default: print(i)

}
2
user6257714

Le comportement standard du commutateur en matière de commutation peut conduire à des bogues similaires à "Go to Fail" .

Fondamentalement, le code ne fait pas toujours exactement ce à quoi il ressemble lorsqu'il le lira, ce qui conduit les auditeurs à ignorer les bogues critiques.

Pour contrer cela, Apple a décidé que les instructions de commutateur ne devraient pas fonctionner de la même manière que = Swift comme norme standard du secteur. En particulier:

  • Il y a une pause automatique à la fin de chaque cas. Il est impossible d'exécuter plus d'une instruction case.
  • S'il est théoriquement possible de manquer l'une des déclarations de cas, le code ne sera pas compilé du tout. Dans Swift, l'une des instructions de cas sera toujours exécutée, quelle que soit la valeur fournie. Si vous fournissez une énumération, chaque valeur doit être traitée. Si une nouvelle valeur est ajoutée à une énumération existante le code ne sera pas compilé tant que de nouvelles instructions case ne seront pas ajoutées Si vous fournissez un entier de 32 bits, vous devez gérer toutes les valeurs possibles d'un entier de 32 bits.
1
Abhi Beckert