Skip to content

Switch #61

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 6 commits into from
Jul 15, 2020
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
24 changes: 13 additions & 11 deletions 1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/solution.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
To precisely match the functionality of `switch`, the `if` must use a strict comparison `'==='`.
برای این که یک `if` دقیقا مانند `switch` عمل کند باید از مقایسه `'==='` استفاده کند:

For given strings though, a simple `'=='` works too.
برای stringها یک مساوی معمولی `'=='` هم کفایت می‌کند

```js no-beautify
if(browser == 'Edge') {
if (browser == 'Edge') {
alert("You've got the Edge!");
} else if (browser == 'Chrome'
|| browser == 'Firefox'
|| browser == 'Safari'
|| browser == 'Opera') {
alert( 'Okay we support these browsers too' );
} else if (
browser == 'Chrome' ||
browser == 'Firefox' ||
browser == 'Safari' ||
browser == 'Opera'
) {
alert('Okay we support these browsers too');
} else {
alert( 'We hope that this page looks ok!' );
alert('We hope that this page looks ok!');
}
```

Please note: the construct `browser == 'Chrome' || browser == 'Firefox' …` is split into multiple lines for better readability.
دقت داشته باشید که این کدها `browser == 'Chrome' || browser == 'Firefox' …` برای خوانایی بیشتر به چند خط تقسیم شده‌اند:

But the `switch` construct is still cleaner and more descriptive.
ولی `switch` تمیزتر و بهتر است.
11 changes: 5 additions & 6 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,24 @@ importance: 5

---

# Rewrite the "switch" into an "if"
# در کد زیر "switch" را به "if" تبدیل کنید

Write the code using `if..else` which would correspond to the following `switch`:
کد زیر را با استفاده از `if..else` بازنویسی کنید

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

case 'Chrome':
case 'Firefox':
case 'Safari':
case 'Opera':
alert( 'Okay we support these browsers too' );
alert('Okay we support these browsers too');
break;

default:
alert( 'We hope that this page looks ok!' );
alert('We hope that this page looks ok!');
}
```

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:
دو چک اول به دو `case` تبدیل می‌شوند. و چک سوم به دو case تقسیم می‌شود:

```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.
دقت داشته باشید: `break` که در انتها آمده ضروری نیست ولی آن را برای این می‌گذاریم که کدمان در آینده درست کار کند..

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.
ممکن است بخواهیم در آینده `case` های بیشتری اضافه کنیم؛ برای مثال `case 4`. در این صورت اگر فراموش می‌کنم که قبل از آن در `case 3` یک break بگذاریم به مشکل برمی‌خوریم. و ارور دریافت می‌کنیم. برای همین است که این `break` آخری را می‌گذاریم.
11 changes: 5 additions & 6 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,22 +2,21 @@ importance: 4

---

# Rewrite "if" into "switch"
# در کد زیر "if" را به ‍"switch" تبدیل کنید

Rewrite the code below using a single `switch` statement:
کد زیر را با استفاده از فقط یک `switch` بازنویسی کنید:

```js run
let a = +prompt('a?', '');

if (a == 0) {
alert( 0 );
alert(0);
}
if (a == 1) {
alert( 1 );
alert(1);
}

if (a == 2 || a == 3) {
alert( '2,3' );
alert('2,3');
}
```

79 changes: 41 additions & 38 deletions 1-js/02-first-steps/14-switch/article.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# The "switch" statement
# دستور "switch"

A `switch` statement can replace multiple `if` checks.
یک دستور ‍‍`switch` می‌تواند جایگزین چند `if` پشت سر هم بشود

It gives a more descriptive way to compare a value with multiple variants.
این دستور توصیف یک متغیر که می‌تواند چند مقدار داشته باشد را راحت‌تر می‌کند.

## The syntax

The `switch` has one or more `case` blocks and an optional default.
یک دستور `switch` یک یا چند بلوک `case` دارد و می‌توان برای آن یک مقدار پیش‌فرض نیست تعریف کرد.

It looks like this:
و بدین شکل نوشته می‌شود:

```js no-beautify
switch(x) {
Expand All @@ -26,13 +26,13 @@ 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).
- در این مرحله چک می‌شود که مقدار `x` دقیقا با مقدار `case` اول برابر باشد. که اینجا مقدار آن `value1` است. سپس برابر بودن آن با (`value2`) چک می‌شود و به همین ترتیب ادامه پیدا می‌کند.
- اگر مقدار برابری پیدا کند، `switch` کد داخل `case` مورد نظر را اجرا می‌کند. و تا زمانی که به نزدیک‌ترین `break` برسد یا به پایان `switch` برسد این کار را ادامه می‌دهد.
- اگر با هیچ‌کدام از `case`ها جور نشود، کد `default` اجرا می‌شود. البته اگر وجود داشته باشد.

## An example
## یک مثال

An example of `switch` (the executed code is highlighted):
یک مثال از دستور `switch` (کد اجراشده هایلایت شده است):

```js run
let a = 2 + 2;
Expand All @@ -43,24 +43,24 @@ switch (a) {
break;
*!*
case 4:
alert( 'Exactly!' );
alert("Exactly!");
break;
*/!*
case 5:
alert( 'Too large' );
alert( "Too large" );
break;
default:
alert( "I don't know such values" );
}
```

Here the `switch` starts to compare `a` from the first `case` variant that is `3`. The match fails.
در اینجا دستور `switch` با مقایسه‌ی `a` با `case` اول شروع می‌کند. که در اینجا مقدار آن `3` است و تطابق ندارند.

Then `4`. That's a match, so the execution starts from `case 4` until the nearest `break`.
سپس به سراغ `4` می‌رود. این یکی برابر است و تطابق پیدا می‌کند. پس اجرای کد از `case 4` شروع می‌شود و تا نزدیک‌ترین `break` ادامه می‌یابد.

**If there is no `break` then the execution continues with the next `case` without any checks.**
**اگر `break` وجود نداشته باشد، `case`های بعدی هم اجرا می‌شوند.**

An example without `break`:
یک مثال بدون `break`:

```js run
let a = 2 + 2;
Expand All @@ -79,18 +79,18 @@ switch (a) {
}
```

In the example above we'll see sequential execution of three `alert`s:
در مثال بالا هر سه `alert` به‌ترتیب اجرا خواهند شد:

```js
alert( 'Exactly!' );
alert( 'Too big' );
alert( "I don't know such values" );
alert('Exactly!');
alert('Too big');
alert("I don't know such values");
```

````smart header="Any expression can be a `switch/case` argument"
Both `switch` and `case` allow arbitrary expressions.
`‍‍‍‍```smart header="هر عبارتی می‌تواند به یک `switch/case` تبدیل شود"
هم در `switch` و هم در `case` می‌توان از عبارت‌های قراردادی استفاده کرد.

For example:
برای مثال:

```js run
let a = "1";
Expand All @@ -99,22 +99,24 @@ let b = 0;
switch (+a) {
*!*
case b + 1:
alert("this runs, because +a is 1, exactly equals b+1");
alert("این کد اجرا می‌شود چرا که +a برابر با 1 است و دقیقا با b+1 مساوی است");
break;
*/!*

default:
alert("this doesn't run");
alert('این اجرا نمی‌شود');
}
```
Here `+a` gives `1`, that's compared with `b + 1` in `case`, and the corresponding code is executed.

در اینجا `+a` برابر با `1` است و وقتی با `b + 1` در `case` مقایسه می‌شود، کد متناظر اجرا می‌شود.

````

## Grouping of "case"
## گروه‌بندی "case"

Several variants of `case` which share the same code can be grouped.
چند `case` مختلف که یک کد دارند، می‌تواند با هم قرار بگیرند.

For example, if we want the same code to run for `case 3` and `case 5`:
برای مثال اگر می‌خواهیم یک کد یکسان برای `case 3` و `case 5` اجرا شود:

```js run no-beautify
let a = 3;
Expand All @@ -125,7 +127,7 @@ switch (a) {
break;

*!*
case 3: // (*) grouped two cases
case 3: // (*) دو case را یک گروه می‌کنیم
case 5:
alert('Wrong!');
alert("Why don't you take a math class?");
Expand All @@ -137,15 +139,15 @@ switch (a) {
}
```

Now both `3` and `5` show the same message.
حالا `3` و `5` پیام یکسانی نمایش می‌دهند.

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`.
این توانایی که می‌توان caseهای مختلف را گروه‌بندی کرد، به این خاطر است که `switch/case` بدون `break` کار می‌کند. اینجا اجرای کد `case 3` از خط `(*)` شروع می‌شود و تا خط `case 5` ادامه پیدا می‌کند. چرا که هیچ `break` وجود ندارد.

## Type matters
## نوع داده Type مهم است

Let's emphasize that the equality check is always strict. The values must be of the same type to match.
اجازه دهید تاکید کنیم که چک برابری کاملا سخت‌گیرانه است. مقدار هر دو باید از یک نوع داده باشد. درغیراین صورت با هم تطابق پیدا نمی‌کنند.

For example, let's consider the code:
برای مثال کد زیر را در نظر بگیرید:

```js run
let arg = prompt("Enter a value?");
Expand All @@ -167,6 +169,7 @@ switch (arg) {
}
```

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. برای `0` و `1` اولین `alert` اجرا می‌شود.
2. برای `2` دومین `alert` اجرا می‌شود.
3. ولی برای `3` مقدار `prompt` یک string است و `"3"` با `3` با `===` برابر نیست. یعنی در `case 3` یک کد مرده داریم. و به‌همین دلیل `default` اجرا می‌شود.
````