Skip to content

The "switch" statement #108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
To precisely match the functionality of `switch`, the `if` must use a strict comparison `'==='`.
Para precisamente se equiparar à funcionalidade do `switch`, o `if` deve utilizar uma comparação exata `'==='`.

For given strings though, a simple `'=='` works too.
Contudo, para certas *strings*, um simples `'=='` também funciona.

```js no-beautify
if(browser == 'Edge') {
alert("You've got the Edge!");
alert("Você usa o Edge!");
} else if (browser == 'Chrome'
|| browser == 'Firefox'
|| browser == 'Safari'
|| browser == 'Opera') {
alert( 'Okay we support these browsers too' );
alert( 'Okay, também suportamos esse navegador.' );
} else {
alert( 'We hope that this page looks ok!' );
alert( 'Esperamos que esta página tenha uma boa apresentação!' );
}
```

Please note: the construct `browser == 'Chrome' || browser == 'Firefox' …` is split into multiple lines for better readability.
Por favor, note: a construção `browser == 'Chrome' || browser == 'Firefox' …` está repartida por múltiplas linhas para melhor leitura.

But the `switch` construct is still cleaner and more descriptive.
Mas a construção `switch` ainda é mais clara e descritiva.
10 changes: 5 additions & 5 deletions 1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ importance: 5

---

# Rewrite the "switch" into an "if"
# Transforme o "switch" num "if"

Write the code using `if..else` which would correspond to the following `switch`:
Escreva o código empregando `if..else` que corresponda ao seguinte `switch`:

```js
switch (browser) {
case 'Edge':
alert( "You've got the Edge!" );
alert( "Você usa o Edge!" );
break;

case 'Chrome':
case 'Firefox':
case 'Safari':
case 'Opera':
alert( 'Okay we support these browsers too' );
alert( 'Okay, também suportamos esse navegador' );
break;

default:
alert( 'We hope that this page looks ok!' );
alert( 'Esperamos que esta página tenha uma boa apresentação!' );
}
```

6 changes: 3 additions & 3 deletions 1-js/02-first-steps/14-switch/2-rewrite-if-switch/solution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The first two checks turn into two `case`. The third check is split into two cases:
As duas primeiras comparações transformam-se em dois `case`. A terceira comparação está divida em dois casos:

```js run
let a = +prompt('a?', '');
Expand All @@ -21,6 +21,6 @@ switch (a) {
}
```

Please note: the `break` at the bottom is not required. But we put it to make the code future-proof.
Por favor, note: o `break` no final não é necessário. Mas o colocamos como segurança no código.

In the future, there is a chance that we'd want to add one more `case`, for example `case 4`. And if we forget to add a break before it, at the end of `case 3`, there will be an error. So that's a kind of self-insurance.
No futuro, poderemos querer colocar mais um `case`, por exemplo `case 4`. E se nos esquecermos de adicionar um break antes dele, no final de `case 3`, ocorrerá um erro. Assim, é uma espécie de prevenção.
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/14-switch/2-rewrite-if-switch/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 4

---

# Rewrite "if" into "switch"
# Transforme o "if" num "switch"

Rewrite the code below using a single `switch` statement:
Reescreva o código abaixo empregando uma única instrução `switch`:

```js run
let a = +prompt('a?', '');
Expand Down
114 changes: 57 additions & 57 deletions 1-js/02-first-steps/14-switch/article.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# The "switch" statement
# A instrução "switch"

A `switch` statement can replace multiple `if` checks.
Uma instrução `switch` pode substituir muitas comparações `if` (se).

It gives a more descriptive way to compare a value with multiple variants.
Ela fornece uma maneira mais descritiva de comparar um valor a múltiplas variantes.

## The syntax
## A sintaxe

The `switch` has one or more `case` blocks and an optional default.
O `switch` tem um ou mais blocos `case` (caso) e um `default` (padrão) opcional.

It looks like this:
Ele se parece com:

```js no-beautify
switch(x) {
case 'value1': // if (x === 'value1')
case 'valor1': // if (x === 'valor1')
...
[break]

case 'value2': // if (x === 'value2')
case 'valor2': // if (x === 'valor2')
...
[break]

Expand All @@ -26,71 +26,71 @@ switch(x) {
}
```

- The value of `x` is checked for a strict equality to the value from the first `case` (that is, `value1`) then to the second (`value2`) and so on.
- If the equality is found, `switch` starts to execute the code starting from the corresponding `case`, until the nearest `break` (or until the end of `switch`).
- If no case is matched then the `default` code is executed (if it exists).
- O valor de `x` é comparado através de uma igualdade exata ao valor do primeiro `case` (isto é, ao `valor1`), a seguir ao do segundo (`valor2`), e assim sucessivamente.
- Se uma igualdade for encontrada, o `switch` começa a executar o código a partir do início do `case` correspondente, até ao próximo `break` (ou até ao fim do `switch`).
- Se nenhum `case` tem uma correspondência, então o código em `default` é executado (se existir).

## An example
## Um exemplo

An example of `switch` (the executed code is highlighted):
Um exemplo de `switch` (o código executado está em destaque):

```js run
let a = 2 + 2;

switch (a) {
case 3:
alert( 'Too small' );
alert( 'Muito baixo' );
break;
*!*
case 4:
alert( 'Exactly!' );
alert( 'Exato!' );
break;
*/!*
case 5:
alert( 'Too big' );
alert( 'Muito alto' );
break;
default:
alert( "I don't know such values" );
alert( "Não conheço tais valores" );
}
```

Here the `switch` starts to compare `a` from the first `case` variant that is `3`. The match fails.
Aqui o `switch` começa por comparar `a` ao valor no primeiro `case`, isto é `3`. A correspondência falha.

Then `4`. That's a match, so the execution starts from `case 4` until the nearest `break`.
A seguir a `4`. Existe uma correspondência, e assim a execução começa a partir do `case 4` até ao próximo `break`.

**If there is no `break` then the execution continues with the next `case` without any checks.**
**Se não existir um `break` então a execução continua pelo próximo `case`, sem mais comparações.**

An example without `break`:
Um exemplo sem `break`:

```js run
let a = 2 + 2;

switch (a) {
case 3:
alert( 'Too small' );
alert( 'Muito baixo' );
*!*
case 4:
alert( 'Exactly!' );
alert( 'Exato!' );
case 5:
alert( 'Too big' );
alert( 'Muito alto' );
default:
alert( "I don't know such values" );
alert( "Não conheço tais valores" );
*/!*
}
```

In the example above we'll see sequential execution of three `alert`s:
No exemplo acima, vemos uma execução sequential de três `alert`'s:

```js
alert( 'Exactly!' );
alert( 'Too big' );
alert( "I don't know such values" );
alert( 'Exato!' );
alert( 'Muito alto' );
alert( "Não conheço tais valores" );
```

````smart header="Any expression can be a `switch/case` argument"
Both `switch` and `case` allow arbitrary expressions.
````smart header="Qualquer expressão pode servir de argumento a 'switch/case'"
Ambos `switch` e `case` permitem expressões arbitrárias.

For example:
Por exemplo:

```js run
let a = "1";
Expand All @@ -99,74 +99,74 @@ let b = 0;
switch (+a) {
*!*
case b + 1:
alert("this runs, because +a is 1, exactly equals b+1");
alert("isto é executado, porque +a é 1, e é exatamente igual a b+1");
break;
*/!*

default:
alert("this doesn't run");
alert("isto não é executado");
}
```
Here `+a` gives `1`, that's compared with `b + 1` in `case`, and the corresponding code is executed.
Aqui `+a` `1`, que é comparado no `case` a `b + 1`, e o código correspondente é executado.
````

## Grouping of "case"
## Grupos de "case"

Several variants of `case` which share the same code can be grouped.
Múltiplas variantes de `case` que partilhem o mesmo código podem ser agrupadas.

For example, if we want the same code to run for `case 3` and `case 5`:
Por exemplo, se quisermos que o mesmo código corra para `case 3` e `case 5`:

```js run no-beautify
let a = 3;
let a = 2 + 2;

switch (a) {
case 4:
alert('Right!');
alert('Certo!');
break;

*!*
case 3: // (*) grouped two cases
case 3: // (*) dois cases agrupados
case 5:
alert('Wrong!');
alert("Why don't you take a math class?");
alert('Errado!');
alert("Porque não tem aulas de matemática?");
break;
*/!*

default:
alert('The result is strange. Really.');
alert('O resultado é estranho. Realmente.');
}
```

Now both `3` and `5` show the same message.
Agora ambos `3` e `5` mostram a mesma mensagem.

The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`.
A habilidade para "agrupar" cases é um efeito secundário de como o `switch/case` funciona sem `break`. Aqui a execução do `case 3` começa pela linha `(*)` e prossegue pelo `case 5`, por não existir `break`.

## Type matters
## O tipo de dados importa

Let's emphasize that the equality check is always strict. The values must be of the same type to match.
Vamos enfatizar que a verificação da igualdade é sempre exata. Os valores devem também ser do mesmo tipo para existir correspondência.

For example, let's consider the code:
Por exemplo, consideremos o código:

```js run
let arg = prompt("Enter a value?");
let arg = prompt("Insira um valor?");
switch (arg) {
case '0':
case '1':
alert( 'One or zero' );
alert( 'Um ou zero' );
break;

case '2':
alert( 'Two' );
alert( 'Dois' );
break;

case 3:
alert( 'Never executes!' );
alert( 'Nunca executa!' );
break;
default:
alert( 'An unknown value' );
alert( 'Um valor desconhecido' );
}
```

1. For `0`, `1`, the first `alert` runs.
2. For `2` the second `alert` runs.
3. But for `3`, the result of the `prompt` is a string `"3"`, which is not strictly equal `===` to the number `3`. So we've got a dead code in `case 3`! The `default` variant will execute.
1. Para `0`, `1`, o primeiro `alert` é executado.
2. Para `2` o segundo `alert` corre.
3. Mas para `3`, o resultado do `prompt` é uma string com o valor `"3"`, que não é estritamente igual `===` ao número `3`. Assim temos código ignorado em `case 3`! A variante `default` será executada.