Die Funktion switch() kann ein knapper Ersatz für eine lange Reihe von if ... else if-Tests sein.
Die Variable, auf die switch() angewendet wird, ist meistens ein String, und dann kannst du die Anführungszeichen im Selektor weglassen.
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"
Beachte, dass Optionen nur dann durchfallen, wenn der Wert leer bleibt, wie bei M im obigen Beispiel.
Du musst keine break-Anweisungen einfügen, wie es in manchen anderen Sprachen nötig ist.
Wenn du auf character-Typen prüfst, ist der letzte Wert ein Standardwert, wie hier.
Bei Ganzzahl-Typen kann kein Standardwert angegeben werden.
dplyr
Das switch in Base R ist ziemlich eingeschränkt: Es führt nur einen exakten Abgleich mit einem einzelnen Eingabewert durch.
Das war sinnvoll, als R 1993 zum ersten Mal veröffentlicht wurde, aber für den modernen Einsatz muss es verbessert werden.
Wie im Konzept Conditionals erwähnt, ist die Paketsammlung tidyverse darauf ausgelegt, die Funktionalität von Base R zu ergänzen (und manchmal zu ersetzen), ohne die Abwärtskompatibilität zu beeinträchtigen.
Du kannst das Paket dplyr in den Gültigkeitsbereich holen, indem du entweder library(dplyr) (für das einzelne Paket) oder library(tidyverse) (für die ganze Sammlung) an den Anfang deines Codes schreibst.
Die Bibliothek dplyr bietet zwei zusätzliche Funktionen rund um switch.
recode_values und replace_values
Diese beiden verwandten Funktionen ermöglichen eine vektorisierte, switch-ähnliche Zuordnung alter Werte zu neuen Werten.
Der Hauptunterschied zwischen ihnen ist, dass recode_values() einen völlig neuen Vektor erzeugt, während replace_values() teilweise Aktualisierungen eines vorhandenen Vektors erlaubt.
Der Abgleich ist weiterhin exakt, aber:
~ statt mit = verknüpft.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 führt die Syntax von case_match noch einen Schritt weiter, indem es jeden beliebigen logischen Ausdruck links von der ~ erlaubt.
Der Eingabevektor (x im Beispiel unten) wird nicht als Argument übergeben, er muss nur schon definiert sein.
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?"
Die Funktion between() ist ebenfalls Teil von dplyr.
In dieser Übung simulieren wir den ersten Zug eines Blackjack-Spiels.
Du bekommst zwei Karten und kannst die offene Karte des Dealers sehen. Alle Karten werden durch einen String dargestellt, zum Beispiel „ace“, „king“, „three“, „two“ usw. Die Werte der einzelnen Karten sind:
| Karte | Wert | Karte | Wert |
|---|---|---|---|
| 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 |
Hinweis: Normalerweise können „ace“-Karten den Wert 1 oder 11 haben, aber der Einfachheit halber gehen wir davon aus, dass sie nur den Wert 11 haben.
Je nach deinen zwei Karten und der Karte des Dealers gibt es eine Strategie für den ersten Zug. Dabei hast du die folgenden Möglichkeiten:
Sie ist zwar noch nicht optimal, aber du folgst der Strategie, die dein Freund Alex entwickelt hat. Sie sieht so aus:
Implementiere eine Funktion parse_card, die den numerischen Wert einer Karte berechnet:
parse_card("ace")
# => 11
Schreibe eine Funktion first_turn, die die oben beschriebene Entscheidungslogik umsetzt:
first_turn(card1, card2, dealer_card)
Hier sind einige Beispiele für die erwarteten Ergebnisse:
first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Melde dich bei Exercism an, um R mit 21 Konzepte111 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.