-
-
Notifications
You must be signed in to change notification settings - Fork 637
Add concept exercise conditionals #1037
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
SleeplessByte
merged 25 commits into
exercism:main
from
junedev:add-concept-exercise-conditionals
Mar 16, 2021
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
cf8fb17
add concepts conditionals and comparison
junedev 8b0c1e4
update comparison concept and fix folder name
junedev 5cb2928
Merge branch 'main' into add-concept-exercise-conditionals
junedev 4fa92cd
general setup for conditionals exercise
junedev a520cca
some fixes in the concepts
junedev fd8bffe
wording fix
junedev 099064b
exemplar solution part 1
junedev 2434605
add exemplar solution part 2
junedev fe8281a
add design file
junedev a6bc9e9
fix typo in config
junedev 7c8215b
add stub and test file
junedev 5bba4ae
add instructions
junedev f15fe04
apply prettier formatting
junedev 3c278ab
more prettier formatting and fixed typo
junedev 5b646c4
add hints
junedev 7aafbab
some small updates
junedev b75cc88
add vehicle-purchase to root config
junedev 20c5aa3
one more prettier fix
junedev 1b58939
Merge branch 'main' into add-concept-exercise-conditionals
junedev 91d1bfe
self-review fixes
junedev 8781962
New line for each sentence and fix links
junedev f43cd65
address some small review comments
junedev 123885e
Merge branch 'main' into add-concept-exercise-conditionals
junedev 1631cec
fix CI issues
junedev 0cb4890
replace table driven tests
junedev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,104 @@ | ||
# About | ||
|
||
TODO: this is a stub that needs more information | ||
## Comparing Numbers | ||
|
||
## Comparing numbers | ||
In JavaScript numbers can be compared using the following relational and equality operators. | ||
|
||
Numbers are considered equal if they have the same value. | ||
| Comparison | Operator | | ||
| ---------------------- | --------- | | ||
| Greater than | `a > b` | | ||
| Greater than or equals | `a >= b` | | ||
| Less than | `a < b` | | ||
| Less than or equals | `a <= b` | | ||
| (Strict) Equals | `a === b` | | ||
| Not (strict) equals | `a !== b` | | ||
|
||
The result of the comparison is always a boolean value, so either `true` or `false`. | ||
|
||
```javascript | ||
1 == 1.0; | ||
1 < 3; | ||
// => true | ||
|
||
2 !== 2; | ||
// => false | ||
|
||
1 === 1.0; | ||
// => true | ||
// Remember, all numbers are floating-points, so this is different syntax for | ||
// All numbers are floating-points, so this is different syntax for | ||
// the exact same value. | ||
``` | ||
|
||
1 === 1n; | ||
## Comparing Strings | ||
|
||
In JavaScript the comparison operators above can also be used to compare strings. | ||
In that case a dictionary (lexicographical) order is applied. | ||
You can find a list of the exact order of all the characters [here][utf-16-list]. | ||
|
||
```javascript | ||
'Apple' > 'Pear'; | ||
// => false | ||
// Strictly checking a number against a bigint will always result in false. | ||
|
||
1 == 1n; | ||
'a' < 'above'; | ||
// => true | ||
// A number is equal to a bigint if they represent the same value. | ||
|
||
1.0 == 1n; | ||
'a' === 'A'; | ||
// => false | ||
``` | ||
|
||
You need to be careful when you compare two variables that appear to contain numeric values but are of type string. | ||
Due to the dictionary order the result will not be the same as comparing values of type number. | ||
|
||
```javascript | ||
10 < 2; | ||
// => false | ||
|
||
'10' < '2'; | ||
// => true (because "1" comes before "2") | ||
``` | ||
|
||
Another way to compare strings is the [localeCompare][mdn-locale-compare] method. | ||
It allows to set a variety of [options][mdn-locale-compare-options] to adjust the way strings are compared. | ||
|
||
## Strict Equality | ||
|
||
You might wonder about the three equal signs for checking equality in JavaScript. | ||
`===` represents the check for _strict equality_ which means that no type conversion is performed and values of different types are always unequal. | ||
|
||
```javascript | ||
'3' === 3; | ||
// => false | ||
// The value on the left has type string, the value on the right has type number. | ||
|
||
1 === 1n; | ||
// => false | ||
// The value on the left has type number, the value on the right has type bigint. | ||
``` | ||
|
||
Using `===` and `!==` is the recommended way of checking equality in JavaScript. | ||
|
||
## Avoiding Implicit Type Conversion | ||
|
||
There is also `==` and `!=` which represents checking for _loose equality_. | ||
You should avoid it because it will apply implicit type conversion before performing the comparison. | ||
The outcomes in these cases are hard to predict and sometimes not what you would expect. | ||
You can read more about it [here][mdn-loose-equals]. | ||
|
||
```javascript | ||
0 == false; | ||
// => true | ||
// A number is equal to a bigint if they represent the same value. | ||
``` | ||
|
||
There are different outcomes when comparing numbers with different types. | ||
In general, only two operands of the type `number` can ever be _strictly equal_ (`===`), and the following can be used for _loose equality_ (`==`): | ||
In theory you can also compare values of different types (e.g., `"1" < 2`). | ||
Then the values will be implicitly converted to determine whether the result is true or false. | ||
Just as checking for loose equality, this is also not recommended for the same reason as mentioned above. | ||
|
||
| A | B | `==` | | ||
| ------ | --------- | --------------------- | | ||
| Number | Undefined | `false` | | ||
| Number | Null | `false` | | ||
| Number | Number | `A === B` | | ||
| Number | String | `A === ToNumber(B)` | | ||
| Number | Boolean | `A === ToNumber(B)` | | ||
| Number | Object | `A == ToPrimitive(B)` | | ||
What should you do instead? | ||
You can apply [explicit type conversion][concept-type-conversion]. | ||
With that you can then ensure values have the correct type before performing the comparison. | ||
Then your code will be easier to understand and less error prone. | ||
|
||
- `ToNumber(X)` attempts to convert its argument `X` to a `number` before comparison. It is equivalent to `+B` (the unary `+` operator). | ||
- `ToPrimitive(X)` attempts to convert its object argument `X` to a primitive value, by attempting to invoke varying sequences of `X.toString` and `X.valueOf` methods on `X`. | ||
[mdn-loose-equals]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality | ||
[concept-type-conversion]: /tracks/javascript/concepts/type-conversion | ||
[utf-16-list]: https://www.fileformat.info/info/charset/UTF-16/list.htm | ||
[mdn-locale-compare]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare | ||
[mdn-locale-compare-options]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#parameters |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,74 @@ | ||
# Introduction | ||
|
||
## Comparing Numbers | ||
|
||
In JavaScript numbers can be compared using the following relational and equality operators. | ||
|
||
| Comparison | Operator | | ||
| ---------------------- | --------- | | ||
| Greater than | `a > b` | | ||
| Greater than or equals | `a >= b` | | ||
| Less than | `a < b` | | ||
| Less than or equals | `a <= b` | | ||
| (Strict) Equals | `a === b` | | ||
| Not (strict) equals | `a !== b` | | ||
|
||
The result of the comparison is always a boolean value, so either `true` or `false`. | ||
|
||
```javascript | ||
1 < 3; | ||
// => true | ||
|
||
2 !== 2; | ||
// => false | ||
|
||
1 === 1.0; | ||
// => true | ||
// All numbers are floating-points, so this is different syntax for | ||
// the exact same value. | ||
``` | ||
|
||
## Comparing Strings | ||
|
||
In JavaScript the comparison operators above can also be used to compare strings. | ||
In that case a dictionary (lexicographical) order is applied. | ||
You can find a list of the exact order of all the characters [here][utf-16-list]. | ||
|
||
```javascript | ||
'Apple' > 'Pear'; | ||
// => false | ||
|
||
'a' < 'above'; | ||
// => true | ||
|
||
'a' === 'A'; | ||
// => false | ||
``` | ||
|
||
## Strict Equality | ||
|
||
You might wonder about the three equal signs for checking equality in JavaScript. | ||
`===` represents the check for _strict equality_ which means that no type conversion is performed and values of different types are always unequal. | ||
|
||
```javascript | ||
'3' === 3; | ||
// => false | ||
// The value on the left has type string, the value on the right has type number. | ||
|
||
1 === 1n; | ||
// => false | ||
// The value on the left has type number, the value on the right has type bigint. | ||
``` | ||
|
||
Using `===` and `!==` is the recommended way of checking equality in JavaScript. | ||
|
||
There is also `==` and `!=` which represents checking for _loose equality_. | ||
You should avoid it because it will apply implicit type conversion before performing the comparison. | ||
The outcomes in these cases are hard to predict and sometimes not what you would expect. | ||
|
||
```javascript | ||
0 == false; | ||
// => true | ||
``` | ||
|
||
[utf-16-list]: https://www.fileformat.info/info/charset/UTF-16/list.htm |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,14 @@ | ||
[] | ||
[ | ||
{ | ||
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#relational_operators", | ||
"description": "MDN: Relational operators" | ||
}, | ||
{ | ||
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#equality_operators", | ||
"description": "MDN: Equality operators" | ||
}, | ||
{ | ||
"url": "https://www.fileformat.info/info/charset/UTF-16/list.htm", | ||
"description": "List of UTF-16 character order" | ||
} | ||
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,141 @@ | ||
# About | ||
|
||
TODO: add information on conditionals concept | ||
## General Syntax | ||
|
||
A common way to conditionally execute logic in JavaScript is the if-statement. | ||
It consists of the `if` keyword, a condition wrapped in round brackets and a code block wrapped in curly brackets. | ||
The code block will only be executed if the condition evaluates to `true`. | ||
|
||
```javascript | ||
if (condition) { | ||
// code that is executed if "condition" is true | ||
} | ||
``` | ||
|
||
It can be used stand-alone or combined with the `else` keyword. | ||
|
||
```javascript | ||
if (condition) { | ||
// code that is executed if "condition" is true | ||
} else { | ||
// code that is executed otherwise | ||
} | ||
``` | ||
|
||
## Nested If-Statements | ||
|
||
To nest another condition into the `else` statement you can use `else if`. | ||
Note that there is no `elseif` keyword in JavaScript. | ||
Instead write `else` followed by another `if` statement. | ||
|
||
```javascript | ||
if (condition1) { | ||
// code that is executed if "condition1" is true | ||
} else if (condition2) { | ||
// code that is executed if "condition2" is true | ||
// but "condition1" was false | ||
} else { | ||
// code that is executed otherwise | ||
} | ||
``` | ||
|
||
Theoretically you can nest as many additional conditions as you want. | ||
In practice you would use a [`switch` statement](/tracks/javascript/concepts/conditionals-switch) instead in these cases. | ||
|
||
```javascript | ||
if (condition1) { | ||
// ... | ||
} else if (condition2) { | ||
// ... | ||
} else if (condition3) { | ||
// ... | ||
} else if (condition4) { | ||
// ... | ||
} else { | ||
// ... | ||
} | ||
``` | ||
|
||
## Condition | ||
|
||
When constructing complex conditions, refer to the [operator precedence table][mdn-operator-precedence] to avoid unnecessary brackets. | ||
|
||
```javascript | ||
if (num >= 0 && num < 1) { | ||
// ... | ||
} | ||
|
||
// The inner brackets are obsolete because relational operators | ||
// have higher precedence than logical operators. | ||
if (num >= 0 && num < 1) { | ||
// ... | ||
} | ||
``` | ||
|
||
Also consider using additional variables to make the code more readable. | ||
junedev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```javascript | ||
const isPositive = num >= 0; | ||
const isSmall = num < 1; | ||
if (isPositive && isSmall) { | ||
// ... | ||
} | ||
``` | ||
|
||
In JavaScript the condition does not have to be of type boolean. | ||
If any other type than boolean is provided in a boolean context like the if-statement, JavaScript will implicitly convert the value to boolean. | ||
Refer to the [type coercion concept][concept-type-coercion] for details on which values are _truthy_ and _falsy_, respectively. | ||
|
||
```javascript | ||
const num = 4; | ||
if (num) { | ||
// this code block will be executed because 4 is truthy | ||
} | ||
``` | ||
|
||
## Short-Hand Notations | ||
|
||
If you only want to execute one statement in the code block for `if` or `else`, it is possible in JavaScript to omit the curly brackets. | ||
|
||
<!-- prettier-ignore-start --> | ||
```javascript | ||
if (condition) doSomething(); | ||
|
||
// or | ||
|
||
if (condition) | ||
doSomething(); | ||
``` | ||
<!-- prettier-ignore-end --> | ||
|
||
This is sometimes used when checking for an error condition for example. | ||
In general it is not recommended because it is easy to forget to add the brackets back in when adding a second statement that should depend on the same condition. | ||
|
||
When writing functions, it is a common pattern to omit the `else` block and use an early `return` in the `if` block instead. | ||
junedev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
In many cases this reduces _nesting_ and makes the code more readable and easier to follow. | ||
|
||
```javascript | ||
function checkNumber(num) { | ||
let message = ''; | ||
|
||
if (num === 0) { | ||
message = 'You passed 0, please provide another number.'; | ||
} else { | ||
message = 'Thanks for passing such a nice number.'; | ||
} | ||
|
||
return message; | ||
} | ||
|
||
// Can also be written as ... | ||
function checkNumber(num) { | ||
if (num === 0) { | ||
return 'You passed 0, please provide another number.'; | ||
} | ||
|
||
return 'Thanks for passing such a nice number.'; | ||
} | ||
``` | ||
|
||
[concept-type-coercion]: /tracks/javascript/concepts/type-coercion | ||
[mdn-operator-precedence]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,34 @@ | ||
# Introduction | ||
|
||
TODO: add introduction for conditionals concept | ||
A common way to conditionally execute logic in JavaScript is the if-statement. | ||
It consists of the `if` keyword, a condition wrapped in round brackets and a code block wrapped in curly brackets. | ||
The code block will only be executed if the condition evaluates to `true`. | ||
|
||
```javascript | ||
if (condition) { | ||
// code that is executed if "condition" is true | ||
} | ||
``` | ||
|
||
It can be used stand-alone or combined with the `else` keyword. | ||
|
||
```javascript | ||
if (condition) { | ||
// code that is executed if "condition" is true | ||
} else { | ||
// code that is executed otherwise | ||
} | ||
``` | ||
|
||
To nest another condition into the `else` statement you can use `else if`. | ||
|
||
```javascript | ||
if (condition1) { | ||
// code that is executed if "condition1" is true | ||
} else if (condition2) { | ||
// code that is executed if "condition2" is true | ||
// but "condition1" was false | ||
} else { | ||
// code that is executed otherwise | ||
} | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.