avnc 016
This commit is contained in:
parent
311341df0b
commit
b5daaec781
445
015_switch_case/015_csharp.md
Normal file
445
015_switch_case/015_csharp.md
Normal file
@ -0,0 +1,445 @@
|
|||||||
|
# Introduction
|
||||||
|
|
||||||
|
The C# programming language is similar to any human written or spoken language.
|
||||||
|
They each support different ways of expressing the same idea. In spoken
|
||||||
|
languages, some words and phrases are more descriptive, accurate, or succinct
|
||||||
|
than others. In the C# programming language, there is more than one way to
|
||||||
|
create branching logic. For example, selections that use `if` statements and
|
||||||
|
selections that use `switch` statements. Depending on the context of your
|
||||||
|
application, one type of selection statement might be more expressive and
|
||||||
|
succinct than the other.
|
||||||
|
|
||||||
|
Suppose working on applications that make extensive use of selections
|
||||||
|
statements. In some cases, `if-elseif-else` constructs are used to produce
|
||||||
|
succinct and expressive code that is easy to read and maintain. In other cases,
|
||||||
|
the `if-elseif-else` constructs produce the required result, but are difficult
|
||||||
|
to read and maintain. You have been tasked with reviewing the code and
|
||||||
|
determining when it is suitable to use a `switch` statement rather than an `if`
|
||||||
|
statement.
|
||||||
|
|
||||||
|
In this module, you'll investigate the use of a `switch` statement to implement
|
||||||
|
branching logic as an alternative to an `if` statement. You'll also work on
|
||||||
|
converting an `if-elseif-else` construct to a `switch-case` construct. During
|
||||||
|
this process, you'll learn to recognize the benefits of choosing one type of
|
||||||
|
selection statement over the other.
|
||||||
|
|
||||||
|
By the end of this module, you'll be able to implement `switch` statements in
|
||||||
|
your application, judge when to use a `switch` statement over an
|
||||||
|
`if-elseif-else` construct, and convert `if-elseif-else` constructs to `switch`
|
||||||
|
statements.
|
||||||
|
|
||||||
|
### Learning objectives
|
||||||
|
|
||||||
|
In this module, you will:
|
||||||
|
|
||||||
|
- Use the `switch-case` construct to match a variable or expression against
|
||||||
|
several possible outcomes.
|
||||||
|
- Convert code that uses an `if-elseif-else` construct into a `switch-case`
|
||||||
|
construct.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exercise
|
||||||
|
|
||||||
|
### Implement a switch statement
|
||||||
|
|
||||||
|
A `switch` statement is a C# selection statement that provides an alternative
|
||||||
|
to an `if-elseif-else` branching construct. The `switch` statement provides
|
||||||
|
advantages over an `if-elseif-else` construct when evaluating a single value
|
||||||
|
against a list of known matching values.
|
||||||
|
|
||||||
|
Consider the following scenario:
|
||||||
|
|
||||||
|
- You're working on an application related to food nutrition. A section of the
|
||||||
|
code deals with fruits.
|
||||||
|
- Your code includes a variable named `fruit` that's used to hold the name of
|
||||||
|
different types of fruit.
|
||||||
|
- You have a list of the 20 fruits that your application is focused on.
|
||||||
|
- You want to branch your code based on the value assigned to `fruit`.
|
||||||
|
|
||||||
|
In this scenario, you can use a `switch` statement to create a separate branch
|
||||||
|
for each type of fruit.
|
||||||
|
|
||||||
|
### How does a switch statement work?
|
||||||
|
|
||||||
|
The `switch` statement chooses one section of code to execute from a list of
|
||||||
|
possible switch sections. The selected switch section is chosen based on a
|
||||||
|
pattern match with the statement's match expression.
|
||||||
|
|
||||||
|
Consider the following code sample that shows the basic structure of `switch`
|
||||||
|
statement:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
switch (fruit) {
|
||||||
|
case "apple":
|
||||||
|
Console.WriteLine($"App will display information for apple.");
|
||||||
|
break;
|
||||||
|
case "banana":
|
||||||
|
Console.WriteLine($"App will display information for banana.");
|
||||||
|
break;
|
||||||
|
case "cherry":
|
||||||
|
Console.WriteLine($"App will display information for cherry.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The match expression (which may also be referred to as the switch expression)
|
||||||
|
is the value following the `switch` keyword, in this case (`fruit`). Each
|
||||||
|
*switch* section is defined by a *case pattern*. Case patterns are constructed
|
||||||
|
using the keyword `case` followed by a value. The first case pattern in this
|
||||||
|
example is: `case "apple":`. Case patterns are Boolean expressions that
|
||||||
|
evaluate to either `true` or `false`. Each switch section includes a small
|
||||||
|
number of code lines that will be executed if the case pattern is a match for
|
||||||
|
the match expression. In this example, if `fruit` is assigned a value of
|
||||||
|
"apple", the first case pattern will evaluate as `true` and that switch section
|
||||||
|
will be executed.
|
||||||
|
|
||||||
|
A switch statement must include at least one switch section, but will normally
|
||||||
|
contain three or more switch sections.
|
||||||
|
|
||||||
|
The switch is best used when:
|
||||||
|
|
||||||
|
- You have a single value (variable or expression) that you want to match
|
||||||
|
against many possible values.
|
||||||
|
- For any given match, you need to execute a couple of lines of code at most.
|
||||||
|
|
||||||
|
> Note
|
||||||
|
> This first example of a `switch` statement is purposefully simple and your
|
||||||
|
examination of the syntax was brief. You will be examining additional features
|
||||||
|
of the `switch` statement when you work through some more advanced scenarios
|
||||||
|
in the sections below.
|
||||||
|
|
||||||
|
It's time to prepare your coding environment and begin developing your own
|
||||||
|
`switch` statements.
|
||||||
|
|
||||||
|
#### Prepare your coding environment
|
||||||
|
|
||||||
|
At the Terminal command prompt, to create a new console application in a
|
||||||
|
specified folder, type dotnet new console -o ./path_to/TestProject and then
|
||||||
|
press Enter.
|
||||||
|
|
||||||
|
This .NET CLI command uses a .NET program template to create a new C# console
|
||||||
|
application project in the specified folder location.
|
||||||
|
|
||||||
|
#### Create and test a switch statement
|
||||||
|
|
||||||
|
Type the following code into the editor:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
int employeeLevel = 200;
|
||||||
|
string employeeName = "John Smith";
|
||||||
|
|
||||||
|
string title = "";
|
||||||
|
|
||||||
|
switch (employeeLevel) {
|
||||||
|
case 100:
|
||||||
|
title = "Junior Associate";
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
title = "Senior Associate";
|
||||||
|
break;
|
||||||
|
case 300:
|
||||||
|
title = "Manager";
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
title = "Senior Manager";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
title = "Associate";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"{employeeName}, {title}");
|
||||||
|
```
|
||||||
|
|
||||||
|
The Program.cs file must be saved before building or running the code.
|
||||||
|
|
||||||
|
At the Terminal command prompt, to run your code, type `dotnet run` and then
|
||||||
|
press Enter.
|
||||||
|
|
||||||
|
Output
|
||||||
|

|
||||||
|
```txt
|
||||||
|
John Smith, Senior Associate
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to review the `switch` statement that you entered.
|
||||||
|
|
||||||
|
Notice that the `switch` statement defines a single code block.
|
||||||
|
|
||||||
|
The `switch` statement defines a single code block that includes a list of
|
||||||
|
`switch` sections. To the right of the switch keyword is a *switch expression*
|
||||||
|
that's enclosed in parentheses.
|
||||||
|
|
||||||
|
Notice the list of switch sections inside the code block.
|
||||||
|
|
||||||
|
The `switch` code block contains a list of switch sections, each of which
|
||||||
|
includes one or more switch labels. In addition, each switch section includes
|
||||||
|
a statement list that will execute if the label is equal to the switch
|
||||||
|
expression defined at the top of the switch statement.
|
||||||
|
|
||||||
|
The switch expression is evaluated against the case labels from top to bottom
|
||||||
|
until a value that is equal to the switch expression is found. If none of the
|
||||||
|
labels are a match, the statement list for the `default` case will be executed.
|
||||||
|
If no default is included, control is transferred to the end point of the
|
||||||
|
switch statement. Each label must provide a value type that matches the type
|
||||||
|
specified in the switch expression.
|
||||||
|
|
||||||
|
> Note
|
||||||
|
> The optional `default` label can appear at any position within the list of
|
||||||
|
switch sections. However, most developers choose to put it last because it
|
||||||
|
makes more sense (logically) to position `default` as the final option.
|
||||||
|
Regardless of the position, the `default` section will be evaluated last.
|
||||||
|
|
||||||
|
In our example:
|
||||||
|
|
||||||
|
- the switch expression is `(employeeLevel)`
|
||||||
|
- each switch section has a single switch label (`case` or `default`).
|
||||||
|
- the matching switch section is defined by `case: 200`, since
|
||||||
|
`employeeLevel = 200`.
|
||||||
|
|
||||||
|
Notice that each switch section is separated from the next.
|
||||||
|
|
||||||
|
Only one switch section is allowed to be executed. This means that execution
|
||||||
|
of a switch section is not permitted to “fall through” to the next switch
|
||||||
|
section. The `break` keyword is one of several ways to end a switch section
|
||||||
|
before it gets to the next section. If you forget the `break` keyword (or,
|
||||||
|
optionally, the `return` keyword) the compiler will generate an error.
|
||||||
|
|
||||||
|
#### Change the level variable value to see how the switch statement evaluates it
|
||||||
|
|
||||||
|
To exercise the default case, let's change the employee's level by modifying the value assignment.
|
||||||
|
|
||||||
|
To modify the value assigned to `employeeLevel`, update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
int employeeLevel = 201;
|
||||||
|
```
|
||||||
|
|
||||||
|
Save your code file, and then run your code.
|
||||||
|
|
||||||
|
Enter `dotnet run` from the Terminal command prompt to run your code.
|
||||||
|
|
||||||
|
Notice that the output has changed.
|
||||||
|
|
||||||
|
Now, when you run the code, you should see the more generic title used.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
John Smith, Associate
|
||||||
|
```
|
||||||
|
|
||||||
|
Since the `employeeLevel` doesn't match any labels, the `default` label is
|
||||||
|
matched.
|
||||||
|
|
||||||
|
#### Modify a switch section to include multiple labels
|
||||||
|
|
||||||
|
Suppose our company decided to give all level 100 employees the title "Senior
|
||||||
|
Associate" -- the same title as level 200 employees. As the developer, you
|
||||||
|
decide to implement this by removing the first switch section belonging to the
|
||||||
|
label `case 100:`, and instead allow both the `case 100:` and `case 200:` labels
|
||||||
|
to execute the same switch section.
|
||||||
|
|
||||||
|
To modify the value assigned to employeeLevel, update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
int employeeLevel = 100;
|
||||||
|
```
|
||||||
|
|
||||||
|
To assign multiple labels to the first switch section, update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
case 100:
|
||||||
|
case 200:
|
||||||
|
title = "Senior Associate";
|
||||||
|
break;
|
||||||
|
```
|
||||||
|
|
||||||
|
When you're finished making changes, your modifications should match the
|
||||||
|
following code:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
int employeeLevel = 100;
|
||||||
|
string employeeName = "John Smith";
|
||||||
|
|
||||||
|
string title = "";
|
||||||
|
|
||||||
|
switch (employeeLevel) {
|
||||||
|
case 100:
|
||||||
|
case 200:
|
||||||
|
title = "Senior Associate";
|
||||||
|
break;
|
||||||
|
case 300:
|
||||||
|
title = "Manager";
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
title = "Senior Manager";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
title = "Associate";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"{employeeName}, {title}");
|
||||||
|
```
|
||||||
|
|
||||||
|
Save your code file, and then run your code.
|
||||||
|
|
||||||
|
Enter `dotnet run` from the Terminal command prompt to run your code.
|
||||||
|
|
||||||
|
You should see the following output:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
John Smith, Senior Associate
|
||||||
|
```
|
||||||
|
|
||||||
|
Both of the case labels `100` and `200` are now paired with the switch section
|
||||||
|
that sets the title to the string value `Senior Associate`.
|
||||||
|
|
||||||
|
### Recap
|
||||||
|
|
||||||
|
Here's the main takeaways you learned about the switch statement:
|
||||||
|
|
||||||
|
- Use the `switch` statement when you have one value with many possible matche
|
||||||
|
s, each match requiring a branch in your code logic.
|
||||||
|
- A single switch section containing code logic can be matched using one or
|
||||||
|
more labels defined by the `case` keyword.
|
||||||
|
- Use the optional `default` keyword to create a label and a switch section
|
||||||
|
that will be used when no other case labels match.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exercise
|
||||||
|
|
||||||
|
### Complete a challenge activity using switch statements
|
||||||
|
|
||||||
|
Code challenges will reinforce what you've learned, and help you gain some
|
||||||
|
confidence before continuing on.
|
||||||
|
|
||||||
|
### Convert to switch statements challenge
|
||||||
|
|
||||||
|
In this challenge, you'll rewrite an `if-elseif-else` construct as a `switch`
|
||||||
|
statement. This challenge should help you see the strengths/weaknesses of the
|
||||||
|
`switch` statement when compared to an `if-elseif-else` construct. Good luck.
|
||||||
|
|
||||||
|
### Code challenge: rewrite if-elseif-else using a switch statement
|
||||||
|
|
||||||
|
You'll start with code that uses an `if-elseif-else` construct to evaluate the
|
||||||
|
components of a product SKU. The SKU (Stock Keeping Unit) is formatted using
|
||||||
|
three coded values: `<product #>-<2-letter color code>-<size code>`. For
|
||||||
|
example, a SKU value of `01-MN-L` corresponds to (sweat shirt)-(maroon)-(large),
|
||||||
|
and the code outputs a description that appears as "Product: Large Maroon
|
||||||
|
Sweat shirt".
|
||||||
|
|
||||||
|
Your challenge is to convert the `if` statement code to a `switch` statement
|
||||||
|
that achieves the same result as the initial code.
|
||||||
|
|
||||||
|
Enter the following code into the code editor:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
// SKU = Stock Keeping Unit.
|
||||||
|
// SKU value format: <product #>-<2-letter color code>-<size code>
|
||||||
|
string sku = "01-MN-L";
|
||||||
|
|
||||||
|
string[] product = sku.Split('-');
|
||||||
|
|
||||||
|
string type = "";
|
||||||
|
string color = "";
|
||||||
|
string size = "";
|
||||||
|
|
||||||
|
if (product[0] == "01") {
|
||||||
|
type = "Sweat shirt";
|
||||||
|
} else if (product[0] == "02") {
|
||||||
|
type = "T-Shirt";
|
||||||
|
} else if (product[0] == "03") {
|
||||||
|
type = "Sweat pants";
|
||||||
|
} else {
|
||||||
|
type = "Other";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (product[1] == "BL") {
|
||||||
|
color = "Black";
|
||||||
|
} else if (product[1] == "MN") {
|
||||||
|
color = "Maroon";
|
||||||
|
} else {
|
||||||
|
color = "White";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (product[2] == "S") {
|
||||||
|
size = "Small";
|
||||||
|
} else if (product[2] == "M") {
|
||||||
|
size = "Medium";
|
||||||
|
} else if (product[2] == "L") {
|
||||||
|
size = "Large";
|
||||||
|
} else {
|
||||||
|
size = "One Size Fits All";
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Product: {size} {color} {type}");
|
||||||
|
```
|
||||||
|
|
||||||
|
Update the code to use a `switch` statement in place of the `if-elseif-else`
|
||||||
|
construct.
|
||||||
|
|
||||||
|
Verify that your output hasn't changed.
|
||||||
|
|
||||||
|
No matter how you do it, your code should produce the following output:
|
||||||
|
|
||||||
|
Output
|
||||||
|

|
||||||
|
```txt
|
||||||
|
Product: Large Maroon Sweat shirt
|
||||||
|
```
|
||||||
|
|
||||||
|
```cs
|
||||||
|
string sku = "01-MN-L";
|
||||||
|
|
||||||
|
string[] product = sku.Split('-');
|
||||||
|
|
||||||
|
string type = "";
|
||||||
|
string color = "";
|
||||||
|
string size = "";
|
||||||
|
|
||||||
|
switch (product[0]) {
|
||||||
|
case "01":
|
||||||
|
type = "Sweat shirt";
|
||||||
|
break;
|
||||||
|
case "02":
|
||||||
|
type = "T-Shirt";
|
||||||
|
break;
|
||||||
|
case "03":
|
||||||
|
type = "Sweat pants";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = "Other";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (product[1]) {
|
||||||
|
case "BL":
|
||||||
|
color = "Black";
|
||||||
|
break;
|
||||||
|
case "MN":
|
||||||
|
color = "Maroon";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = "White";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (product[2]) {
|
||||||
|
case "S":
|
||||||
|
size = "Small";
|
||||||
|
break;
|
||||||
|
case "M":
|
||||||
|
size = "Medium";
|
||||||
|
break;
|
||||||
|
case "L":
|
||||||
|
size = "Large";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
size = "One Size Fits All";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Product: {size} {color} {type}");
|
||||||
|
```
|
53
015_switch_case/rewrite_ifs/Program.cs
Normal file
53
015_switch_case/rewrite_ifs/Program.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// SKU = Stock Keeping Unit.
|
||||||
|
// SKU value format: <product #>-<2-letter color code>-<size code>
|
||||||
|
string sku = "01-MN-L";
|
||||||
|
|
||||||
|
string[] product = sku.Split('-');
|
||||||
|
|
||||||
|
string type = "";
|
||||||
|
string color = "";
|
||||||
|
string size = "";
|
||||||
|
|
||||||
|
switch (product[0]) {
|
||||||
|
case "01":
|
||||||
|
type = "Sweat shirt";
|
||||||
|
break;
|
||||||
|
case "02":
|
||||||
|
type = "T-Shirt";
|
||||||
|
break;
|
||||||
|
case "03":
|
||||||
|
type = "Sweat pants";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = "Other";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (product[1]) {
|
||||||
|
case "BL":
|
||||||
|
color = "Black";
|
||||||
|
break;
|
||||||
|
case "MN":
|
||||||
|
color = "Maroon";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = "White";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (product[2]) {
|
||||||
|
case "S":
|
||||||
|
size = "Small";
|
||||||
|
break;
|
||||||
|
case "M":
|
||||||
|
size = "Medium";
|
||||||
|
break;
|
||||||
|
case "L":
|
||||||
|
size = "Large";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
size = "One Size Fits All";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Product: {size} {color} {type}");
|
10
015_switch_case/rewrite_ifs/rewrite_ifs.csproj
Normal file
10
015_switch_case/rewrite_ifs/rewrite_ifs.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
504
016_Iterate_using_for_statement/016_csharp.md
Normal file
504
016_Iterate_using_for_statement/016_csharp.md
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
# Iterate through a code block using for statement in C#
|
||||||
|
|
||||||
|
Use the for iteration statement to loop a pre-set number of times and control the iteration process.
|
||||||
|
|
||||||
|
### Learning objectives
|
||||||
|
|
||||||
|
After you complete this module, you'll be able to:
|
||||||
|
|
||||||
|
- Use the `for` statement to loop through a block of code
|
||||||
|
- Modify how the .NET Runtime executes the looping logic, changing the value
|
||||||
|
of the iterator, the condition and the pattern
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
There are several ways to add looping logic in your application, and depending
|
||||||
|
on the context, each provides a nuanced set of features that have both pros
|
||||||
|
and cons.
|
||||||
|
|
||||||
|
Suppose you're about to start working on an application that processes string
|
||||||
|
and numeric data using single dimensional and multidimensional arrays. After
|
||||||
|
an initial review, you realize that `foreach` statements do not support
|
||||||
|
looping logic that will be required in many cases. You'll need another
|
||||||
|
approach for iterating through multidimensional arrays, and for situations
|
||||||
|
where `foreach` loops don't provide the level of iteration control that's
|
||||||
|
needed. You need to gain experience using `for` statements if you're going to
|
||||||
|
succeed on this project.
|
||||||
|
|
||||||
|
In this module, you'll begin by writing `for` statements that iterate a
|
||||||
|
specific number of times. After implementing a basic `for` statement, you'll
|
||||||
|
learn how to implement `for` statements that iterate backwards through an array,
|
||||||
|
skip over array elements during an iteration, or process only specified
|
||||||
|
elements of an array (by changing the `for` statement's initializer, condition,
|
||||||
|
and iterator).
|
||||||
|
|
||||||
|
By the end of this module, you'll be able to use `for` statements to implement
|
||||||
|
looping logic when foreach statements don't support the scenario.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exercise
|
||||||
|
|
||||||
|
### Create and configure for iteration loops
|
||||||
|
|
||||||
|
On the surface, the `for` statement is another iteration statement that allows
|
||||||
|
you to iterate through a code block and thereby change the flow of execution
|
||||||
|
of your code. However, once we examine how each works, we can better identify
|
||||||
|
the nuances of each iteration statement and when to use them.
|
||||||
|
|
||||||
|
### What is the `for` statement?
|
||||||
|
|
||||||
|
The `for` statement iterates through a code block a specific number of times.
|
||||||
|
This level of control makes the `for` statement unique among the other
|
||||||
|
iteration statements. The `foreach` statement iterates through a block of code
|
||||||
|
once for each item in a sequence of data like an array or collection. The
|
||||||
|
`while` statement iterates through a block of code until a condition is met.
|
||||||
|
|
||||||
|
Furthermore, the `for` statement gives you much more control over the process
|
||||||
|
of iteration by exposing the conditions for iteration.
|
||||||
|
|
||||||
|
In this exercise, you'll use the `for` statement, learning how to control the
|
||||||
|
iteration's pre-condition, completion condition, its iteration pattern and more.
|
||||||
|
Also, you'll learn of common use cases for the `for` statement.
|
||||||
|
|
||||||
|
Okay, now let's prepare our coding environment and begin our examination of
|
||||||
|
code samples that implement a `for` statement.
|
||||||
|
|
||||||
|
#### Prepare your coding environment
|
||||||
|
|
||||||
|
At the Terminal command prompt, to create a new console application in a
|
||||||
|
specified folder, type "dotnet new console -o ./path_to/TestProject" and then
|
||||||
|
press Enter.
|
||||||
|
|
||||||
|
This .NET CLI command uses a .NET program template to create a new C# console
|
||||||
|
application project in the specified folder location.
|
||||||
|
|
||||||
|
### Write a basic for statement
|
||||||
|
|
||||||
|
Ensure that you have Program.cs open in the code editor.
|
||||||
|
|
||||||
|
> Note
|
||||||
|
> Program.cs should be empty. If if isn't, select and delete all code lines.
|
||||||
|
|
||||||
|
Type the following code into the code editor.
|
||||||
|
|
||||||
|
```cs
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Console.WriteLine(i);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This code presents a simple `for` statement that loops through its code block 10
|
||||||
|
times, printing the current value of `i`.
|
||||||
|
|
||||||
|
The Program.cs file must be saved before building or running the code.
|
||||||
|
|
||||||
|
At the Terminal command prompt, to run your code, type `dotnet run` and then
|
||||||
|
press Enter.
|
||||||
|
|
||||||
|
You should see the following output.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to identify the six parts of the `for` statement.
|
||||||
|
|
||||||
|
The `for` statement includes the following six parts:
|
||||||
|
|
||||||
|
1. The `for` keyword.
|
||||||
|
2. A set of parentheses that defines the conditions of `for` iteration. The
|
||||||
|
parentheses contain three distinct parts, separated by the end of statement
|
||||||
|
operator, a semi-colon.
|
||||||
|
3. The first part defines and initializes the iterator variable. In this
|
||||||
|
example: `int i = 0`. This section is referred to as the initializer.
|
||||||
|
4. The second part defines the completion condition. In this example: `i < 10`.
|
||||||
|
In other words, the runtime will continue to iterate over the code in the code
|
||||||
|
block below the `for` statement while `i` is less than `10`. When `i` becomes
|
||||||
|
equal to `10`, the runtime stops executing the `for` statement's code block. The
|
||||||
|
docs refer to this section as the condition.
|
||||||
|
5. The third part defines the action to take after each iteration. In this case,
|
||||||
|
after each iteration, `i++` will increment the value of `i` by 1. The docs
|
||||||
|
refer to this section as the **iterator**.
|
||||||
|
6. Finally, the code block. The code block contains the code that will be
|
||||||
|
executed for each iteration. Notice that the value of `i` is referenced inside
|
||||||
|
of the code block. The docs refer to this section as the body.
|
||||||
|
|
||||||
|
Given our rules for naming variables, you may wonder if `i` is a valid name
|
||||||
|
for the variable that holds the current iteration. In this case, `i` is
|
||||||
|
considered by most to be valid. Other popular choices are `x` and `counter`.
|
||||||
|
The name `j` is also used in those situations when you have an outer `for`
|
||||||
|
statement that uses `i`, and need to create an iteration variable for an inner
|
||||||
|
`for` statement.
|
||||||
|
|
||||||
|
> Note
|
||||||
|
> All three sections (initializer, condition, and iterator) are optional.
|
||||||
|
However, in practice, typically all three sections are used.
|
||||||
|
|
||||||
|
### Change the iteration conditions
|
||||||
|
|
||||||
|
As we stated at the outset, the `for` statement has two unique qualities among
|
||||||
|
iteration statements.
|
||||||
|
|
||||||
|
- The `for` statement should be used when you know the number of times you
|
||||||
|
need to iterate through a block of code ahead of time.
|
||||||
|
- The `for` statement allows you to control the way in which each iteration is
|
||||||
|
handled.
|
||||||
|
|
||||||
|
What if we needed to iterate through a block of code, but want to count down instead of counting up?
|
||||||
|
|
||||||
|
Update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
for (int i = 10; i >= 0; i--) {
|
||||||
|
Console.WriteLine(i);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to review your updated code.
|
||||||
|
|
||||||
|
By changing the three parts of the `for` statement, we change its behavior.
|
||||||
|
|
||||||
|
- We initialize the iteration variable to 10.
|
||||||
|
- We change the completion condition to exit the `for` statement when `i` is
|
||||||
|
less than `0`.
|
||||||
|
- We change the pattern of the iterator to subtract `1` from `i` each time we
|
||||||
|
complete an iteration.
|
||||||
|
|
||||||
|
Save your code file, and then run your code.
|
||||||
|
|
||||||
|
Enter `dotnet run` from the Terminal command prompt to run your code.
|
||||||
|
|
||||||
|
Notice that the output has changed.
|
||||||
|
|
||||||
|
When you run the code, you'll see the following output.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
10
|
||||||
|
9
|
||||||
|
8
|
||||||
|
7
|
||||||
|
6
|
||||||
|
5
|
||||||
|
4
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Experiment with the iterator's pattern
|
||||||
|
|
||||||
|
What if we wanted to skip past certain values in the iterator variable?
|
||||||
|
|
||||||
|
Use the code editor to update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
for (int i = 0; i < 10; i += 3) {
|
||||||
|
Console.WriteLine(i);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to review your updated code.
|
||||||
|
|
||||||
|
Instead of incrementing or decrementing the value of the iterator variable by
|
||||||
|
`1`, we use `i += 3` to skip two values after each iteration.
|
||||||
|
|
||||||
|
Save your code file, and then use run your code.
|
||||||
|
|
||||||
|
Enter `dotnet run` from the Terminal command prompt to run your code.
|
||||||
|
|
||||||
|
Notice how the output has changed.
|
||||||
|
|
||||||
|
When you run the code, you'll see the following output.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
0
|
||||||
|
3
|
||||||
|
6
|
||||||
|
9
|
||||||
|
```
|
||||||
|
|
||||||
|
Admittedly, you won't do this sort of thing often, but hopefully you can
|
||||||
|
appreciate that you have a fine grained level of control over the iterations
|
||||||
|
should you ever need it.
|
||||||
|
|
||||||
|
### Use the break keyword to break the iteration statement
|
||||||
|
|
||||||
|
What if we need to exit the iteration statement prematurely based on some
|
||||||
|
condition? We can use the `break` keyword.
|
||||||
|
|
||||||
|
Use the code editor to update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Console.WriteLine(i);
|
||||||
|
if (i == 7) break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to review the use of the `break` keyword in your updated code.
|
||||||
|
|
||||||
|
We first saw the `break` keyword in the module "Branch the flow of code using
|
||||||
|
the switch-case construct in C#". As it turns out, we can use the `break`
|
||||||
|
keyword to exit out of iteration statements as well.
|
||||||
|
|
||||||
|
Save your code file, and then run your code.
|
||||||
|
|
||||||
|
When you run the code, you'll see the following output.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
```
|
||||||
|
|
||||||
|
### Loop through each element of an array
|
||||||
|
|
||||||
|
A common usage `for` the for statement is to iterate through an array of
|
||||||
|
elements, especially if you need some control over the manner in which the
|
||||||
|
iteration happens. While the `foreach` iterates through every element of the
|
||||||
|
array, the for statement can be tweaked to provide more customization.
|
||||||
|
|
||||||
|
Update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
string[] names = { "Alex", "Eddie", "David", "Michael" };
|
||||||
|
for (int i = names.Length - 1; i >= 0; i--) {
|
||||||
|
Console.WriteLine(names[i]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to review your updated code.
|
||||||
|
|
||||||
|
First off, notice that we have instantiated a string array named `names` that
|
||||||
|
contains four names.
|
||||||
|
|
||||||
|
Next, notice that we are using the `Array.Length` property to get the number
|
||||||
|
of elements in the array, and that we are using this value to initialize our
|
||||||
|
iterator variable (`int i = names.Length - 1`). We subtract 1 from the value
|
||||||
|
because the index number for array elements is zero-based (the index numbers
|
||||||
|
of the four elements are 0-3).
|
||||||
|
|
||||||
|
Finally, notice we have chosen iterate through the array backwards--something
|
||||||
|
that we are unable to do with the `foreach` statement. We use the value of the
|
||||||
|
iteration variable inside the code block to specify the index number of the
|
||||||
|
array elements (`names[i]`).
|
||||||
|
|
||||||
|
Save your code file, and then enter `dotnet run` from the Terminal command
|
||||||
|
prompt to run your code.
|
||||||
|
|
||||||
|
Output
|
||||||
|

|
||||||
|
```txt
|
||||||
|
Michael
|
||||||
|
David
|
||||||
|
Eddie
|
||||||
|
Alex
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note
|
||||||
|
> We could have iterated forward through the array elements by constructing
|
||||||
|
the `for` statement as follows: `for (int i = 0; i < names.Length; i++)`.
|
||||||
|
|
||||||
|
### Examine the limitation of the foreach statement
|
||||||
|
|
||||||
|
What if you want to update a value in the array during a `foreach` iteration?
|
||||||
|
|
||||||
|
Use the Visual Studio Code Editor to update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
string[] names = { "Alex", "Eddie", "David", "Michael" };
|
||||||
|
foreach (var name in names) {
|
||||||
|
// Can't do this:
|
||||||
|
if (name == "David") name = "Sammy";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Save your code file, and then enter `dotnet run` from the Terminal command
|
||||||
|
prompt to run your code.
|
||||||
|
|
||||||
|
Notice the error message that is displayed.
|
||||||
|
|
||||||
|
If you attempt to compile and run this code, you will see an exception.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Cannot assign to name because it is a 'foreach iteration variable'
|
||||||
|
```
|
||||||
|
|
||||||
|
In other words, you can't reassign the value of `name` because it is part of
|
||||||
|
the `foreach` iteration's inner implementation.
|
||||||
|
|
||||||
|
### Overcoming the limitation of the foreach statement using the for statement
|
||||||
|
|
||||||
|
Let's try using a `for` statement to modify the contents of an array inside
|
||||||
|
the iteration code block.
|
||||||
|
|
||||||
|
Use the code editor to update your code as follows:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
string[] names = { "Alex", "Eddie", "David", "Michael" };
|
||||||
|
for (int i = 0; i < names.Length; i++)
|
||||||
|
if (names[i] == "David") names[i] = "Sammy";
|
||||||
|
|
||||||
|
foreach (var name in names) Console.WriteLine(name);
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a minute to review your updated code.
|
||||||
|
|
||||||
|
Notice that we removed the curly braces from the code blocks that contained
|
||||||
|
only a single line of code. This revision uses the same technique that we
|
||||||
|
talked about in the module "Control variable scope and logic using code blocks
|
||||||
|
in C#". Many developers find this style difficult to read, while others prefer
|
||||||
|
this abbreviated style because it helps them write more succinctly and more
|
||||||
|
expressively. If you find this code difficult to read, or if you just don't
|
||||||
|
prefer this style, rest assured that the curly braces can always be used in
|
||||||
|
your code blocks. If you want, update the code in the Editor panel with the
|
||||||
|
following code:
|
||||||
|
|
||||||
|
```cs
|
||||||
|
string[] names = { "Alex", "Eddie", "David", "Michael" };
|
||||||
|
|
||||||
|
for (int i = 0; i < names.Length; i++) {
|
||||||
|
if (names[i] == "David") {
|
||||||
|
names[i] = "Sammy";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var name in names) {
|
||||||
|
Console.WriteLine(name);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Save your code file, and then enter `dotnet run` from the Terminal command
|
||||||
|
prompt to run your code.
|
||||||
|
|
||||||
|
Notice that the code runs without error and generates the desired output.
|
||||||
|
|
||||||
|
When you run the code, you'll see the following output.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Alex
|
||||||
|
Eddie
|
||||||
|
Sammy
|
||||||
|
Michael
|
||||||
|
```
|
||||||
|
|
||||||
|
Since the array isn't directly part of the iteration statement's implementation,
|
||||||
|
you can change values inside of the array.
|
||||||
|
|
||||||
|
### Recap
|
||||||
|
|
||||||
|
Here are a few of the takeaways from this unit:
|
||||||
|
|
||||||
|
- The `for` iteration statement allows you to iterate through a block of code a
|
||||||
|
specific number of times.
|
||||||
|
- The `for` iteration statement allows you to control every aspect of the
|
||||||
|
iteration's mechanics by altering the three conditions inside the parentheses:
|
||||||
|
the initializer, condition, and iterator.
|
||||||
|
- It's common to use the `for` statement when you need to control how you want
|
||||||
|
to iterate through each item in an array.
|
||||||
|
- If your code block has only one line of code, you can eliminate the curly
|
||||||
|
braces and white space if you wish.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exercise
|
||||||
|
|
||||||
|
### Complete a challenge activity using for and if statements
|
||||||
|
|
||||||
|
Code challenges will reinforce what you've learned and help you gain some
|
||||||
|
confidence before continuing on.
|
||||||
|
|
||||||
|
### FizzBuzz challenge
|
||||||
|
|
||||||
|
FizzBuzz is a popular coding challenge and interview question. It exercises
|
||||||
|
your understanding of the `for` statement, the `if` statement, the `%`
|
||||||
|
remainder operator, and your command of basic logic.
|
||||||
|
|
||||||
|
### Code challenge - implement the FizzBuzz challenge rules
|
||||||
|
|
||||||
|
Here are the FizzBuzz rules that you need to implement in your code project:
|
||||||
|
|
||||||
|
- Output values from 1 to 100, one number per line, inside the code block of
|
||||||
|
an iteration statement.
|
||||||
|
- When the current value is divisible by 3, print the term `Fizz` next to the
|
||||||
|
number.
|
||||||
|
- When the current value is divisible by 5, print the term `Buzz` next to the
|
||||||
|
number.
|
||||||
|
- When the current value is divisible by both 3 and 5, print the term `FizzBuzz`
|
||||||
|
next to the number.
|
||||||
|
|
||||||
|
Write the code that implements each rule.
|
||||||
|
|
||||||
|
> Important
|
||||||
|
> You will need to understand how to use the `%` remainder operator to determine
|
||||||
|
if a number is divisible by another number evenly. We covered this in the
|
||||||
|
module "Perform basic operations on numbers in C#".
|
||||||
|
|
||||||
|
Run your application and verify that your output meets the requirements.
|
||||||
|
|
||||||
|
No matter how you have nested you iteration and conditional statements, your
|
||||||
|
code should produce the following output.
|
||||||
|
|
||||||
|
```txt
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3 - Fizz
|
||||||
|
4
|
||||||
|
5 - Buzz
|
||||||
|
6 - Fizz
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9 - Fizz
|
||||||
|
10 - Buzz
|
||||||
|
11
|
||||||
|
12 - Fizz
|
||||||
|
13
|
||||||
|
14
|
||||||
|
15 - FizzBuzz
|
||||||
|
16
|
||||||
|
17
|
||||||
|
18 - Fizz
|
||||||
|
19
|
||||||
|
20 - Buzz
|
||||||
|
21 - Fizz
|
||||||
|
22
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note
|
||||||
|
> We only show the first 22 values, but your output should continue to 100. As
|
||||||
|
you can see, the number `15` is divisible by both 3 and 5, so we print
|
||||||
|
`FizzBuzz` next to that number.
|
||||||
|
|
||||||
|
```cs
|
||||||
|
for (int i = 1; i <= 100; i++) {
|
||||||
|
string output = "";
|
||||||
|
if (i%3 == 0) {
|
||||||
|
output += "Fizz";
|
||||||
|
}
|
||||||
|
if (i%5 == 0) {
|
||||||
|
output += "Buzz";
|
||||||
|
}
|
||||||
|
Console.WriteLine($"{i} {output}");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
22
016_Iterate_using_for_statement/fizzbuzz/Program.cs
Normal file
22
016_Iterate_using_for_statement/fizzbuzz/Program.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
for (int i = 1; i <= 100; i++) {
|
||||||
|
string output = "";
|
||||||
|
if (i%3 == 0) {
|
||||||
|
output += "Fizz";
|
||||||
|
}
|
||||||
|
if (i%5 == 0) {
|
||||||
|
output += "Buzz";
|
||||||
|
}
|
||||||
|
Console.WriteLine($"{i} {output}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// suggested solution
|
||||||
|
// for (int i = 1; i < 101; i++) {
|
||||||
|
// if ((i % 3 == 0) && (i % 5 == 0))
|
||||||
|
// Console.WriteLine($"{i} - FizzBuzz");
|
||||||
|
// else if (i % 3 == 0)
|
||||||
|
// Console.WriteLine($"{i} - Fizz");
|
||||||
|
// else if (i % 5 == 0)
|
||||||
|
// Console.WriteLine($"{i} - Buzz");
|
||||||
|
// else
|
||||||
|
// Console.WriteLine($"{i}");
|
||||||
|
// }
|
10
016_Iterate_using_for_statement/fizzbuzz/fizzbuzz.csproj
Normal file
10
016_Iterate_using_for_statement/fizzbuzz/fizzbuzz.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -17,3 +17,7 @@ Following
|
|||||||
- [Conventions](./010_conventions/010_csharp.md)
|
- [Conventions](./010_conventions/010_csharp.md)
|
||||||
- [Guided Project - foreach](./011_foreach_array_1/011_csharp.md)
|
- [Guided Project - foreach](./011_foreach_array_1/011_csharp.md)
|
||||||
- [Challenge Project - foreach](./012_foreach_array_2/012_csharp.md)
|
- [Challenge Project - foreach](./012_foreach_array_2/012_csharp.md)
|
||||||
|
- [Evaluate Boolean expressions](/013_eval_boolean_expressions/013_csharp.md)
|
||||||
|
- [Control variable scope and logic](/014_scope_and_logic/014_csharp.md)
|
||||||
|
- [switch case construct](./015_switch_case/015_csharp.md)
|
||||||
|
- [switch case construct](/016_Iterate_using_for_statement/016_csharp.md)
|
||||||
|
Loading…
Reference in New Issue
Block a user