La fonction switch() peut remplacer de façon concise une longue série de tests if ... else if.
La variable sur laquelle on fait un switch est le plus souvent une string, et dans ce cas les guillemets peuvent être omis dans le sélecteur.
star <- function(type) {
switch(type,
M = , # will "fall through" if no value given
K = "red dwarf",
G = "Earth-like",
"bigger star" # only correct for O,B,A,F
)
}
> star("M")
[1] "red dwarf"
Note que les options ne passent à la suivante que si la valeur est laissée vide, comme avec M dans l'exemple ci-dessus.
Il n'est pas nécessaire d'inclure des instructions break, contrairement à certains autres langages.
Quand on fait un switch sur des types character, la dernière valeur est une valeur par défaut, comme ici.
Avec les types entiers, aucune valeur par défaut ne peut être donnée.
dplyr
Le switch de R de base est assez limité : il ne fait qu'une correspondance exacte avec une seule entrée.
Cela semblait raisonnable lors de la première version de R en 1993, mais mérite des améliorations pour un usage moderne.
Comme mentionné dans le concept Conditionals, l'ensemble de paquets tidyverse est conçu pour compléter (et parfois remplacer) les fonctionnalités de R de base sans nuire à la rétrocompatibilité.
Pour mettre le paquet dplyr dans la portée, il suffit d'ajouter soit library(dplyr) (pour le paquet seul) soit library(tidyverse) (pour l'ensemble de la collection) en haut de ton code.
La bibliothèque dplyr fournit deux fonctions supplémentaires liées à switch.
recode_values et replace_values
Ces deux fonctions apparentées permettent une correspondance vectorisée, proche du switch, entre d'anciennes valeurs et de nouvelles valeurs.
La principale différence entre elles est que recode_values() crée un vecteur entièrement nouveau, tandis que replace_values() permet des mises à jour partielles d'un vecteur existant.
La correspondance reste exacte, mais :
~ au lieu de =.library(dplyr)
x <- c("a", "b", "a", "d", "b", NA, "c", "e", "z")
recode_values(
x,
"a" ~ 1,
"b" ~ 2,
"c" ~ 3,
c("d", "e") ~ 4, # either "d' or "e" will match
NA ~ 0, # matches missing values
default = 100 # note the different syntax for the default
)
#> [1] 1 2 1 4 2 0 3 4 100
case_when
case_when pousse la syntaxe de case_match encore plus loin, en autorisant n'importe quelle expression logique à gauche du ~.
Le vecteur d'entrée (x dans l'exemple ci-dessous) n'est pas fourni comme argument, il doit simplement être déjà défini.
x <- 1:10
case_when(
x < 3 ~ "low",
between(x, 3, 5) ~ "mid",
between(x, 6, 8) ~ "high",
.default = "what?"
)
#> [1] "low" "low" "mid" "mid" "mid" "high" "high" "high" "what?" "what?"
La fonction between() fait aussi partie de dplyr.
Dans cet exercice, on va simuler le premier tour d'une partie de Blackjack.
Tu vas recevoir deux cartes et tu pourras voir la carte visible du croupier. Toutes les cartes sont représentées par une string telle que « ace », « king », « three », « two », etc. Voici la valeur de chaque carte :
| carte | valeur | carte | valeur |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | other | 0 |
Remarque : les as peuvent généralement valoir 1 ou 11, mais par souci de simplicité, on considérera qu'ils ne peuvent valoir que 11.
Selon tes deux cartes et la carte du croupier, il existe une stratégie pour le premier tour de la partie, avec les options suivantes :
Bien qu'elle ne soit pas encore optimale, tu vas suivre la stratégie que ton ami Alex a mise au point, qui est la suivante :
Implémente une fonction parse_card qui calcule la valeur numérique d'une carte :
parse_card("ace")
# => 11
Écris une fonction first_turn qui implémente la logique de décision décrite plus haut :
first_turn(card1, card2, dealer_card)
Voici quelques exemples de résultats attendus :
first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Inscris-toi sur Exercism pour apprendre et maîtriser R avec 21 concepts111 exercices, et un vrai mentorat humain, le tout gratuitement.