A função switch() pode ser um substituto conciso para uma longa série de testes if ... else if.
A variável sobre a qual se faz o switch é, habitualmente, uma string e, nesse caso, as aspas podem ser omitidas do seletor.
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"
Repara que as opções só passam para a seguinte se o valor for deixado em branco, como acontece com M no exemplo acima.
Não é preciso incluir instruções break, ao contrário do que acontece em algumas outras linguagens.
Quando se faz o switch sobre o tipo character, o valor final é um valor predefinido, como aqui.
Com tipos inteiros, não é possível indicar nenhum valor predefinido.
dplyr
O switch do R base é bastante limitado: só faz uma correspondência exata com um único valor de entrada.
Isto parecia razoável quando o R foi lançado, em 1993, mas precisa de melhorias para o uso moderno.
Como foi referido no Conceito Conditionals, a coleção de pacotes tidyverse foi concebida para complementar (e, por vezes, substituir) a funcionalidade do R base sem afetar a compatibilidade retrocompatível.
O pacote dplyr pode ser trazido para o âmbito adicionando library(dplyr) (para o pacote individual) ou library(tidyverse) (para a coleção completa) ao topo do teu código.
A biblioteca dplyr fornece duas funções extra relacionadas com o switch.
recode_values e replace_values
Estas duas funções relacionadas permitem um mapeamento vetorizado, semelhante ao switch, de valores antigos para valores novos.
A principal diferença entre elas é que recode_values() cria um vetor completamente novo, enquanto replace_values() permite atualizações parciais de um vetor existente.
A correspondência continua a ser exata, mas:
~ em vez 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
A função case_when leva a sintaxe do case_match um passo mais além, ao permitir qualquer expressão lógica à esquerda do ~.
O vetor de entrada (x no exemplo abaixo) não é fornecido como argumento, só precisa de já estar definido.
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?"
A função between() também faz parte do dplyr.
Neste exercício vamos simular a primeira jogada de um jogo de Blackjack.
Vais receber duas cartas e vais poder ver a carta destapada do dealer. Todas as cartas são representadas por uma string como "ace", "king", "three", "two", etc. Os valores de cada carta são:
| carta | valor | carta | valor |
|---|---|---|---|
| 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 |
Nota: Normalmente, os ases podem valer 1 ou 11, mas, para simplificar, vamos assumir que só podem valer 11.
Dependendo das tuas duas cartas e da carta do dealer, existe uma estratégia para a primeira jogada, na qual tens as seguintes opções:
Embora ainda não seja a ideal, vais seguir a estratégia que o teu amigo Alex anda a desenvolver, que é a seguinte:
Implementa uma função parse_card para calcular o valor numérico de uma carta:
parse_card("ace")
# => 11
Escreve uma função first_turn que implementa a lógica de decisão descrita acima:
first_turn(card1, card2, dealer_card)
Aqui estão alguns exemplos dos resultados esperados:
first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Inscreve-te no Exercism para aprenderes e dominares R com 21 conceitos111 exercícios, e mentoria humana real, tudo grátis.