{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "048eaaae",
   "metadata": {},
   "source": [
    "```{index} statement; for\n",
    "```\n",
    "\n",
    "(for-statement)=\n",
    "\n",
    "# The `for` Statement\n",
    "\n",
    "The `for` statement executes a statement or a block of statements\n",
    "while a specified **Boolean expression** evaluates to true. Such evaluation involves\n",
    "comparing the local loop counter variable (an **integer counter** that increments/decrements over every loop)\n",
    "to a preset value. Since the number of loops is controlled by comparing the counter with the **preset value**,\n",
    "you need to specify the preset value to decide the number of times you want to run the code block when defining\n",
    "a `for` loop statement.\n",
    "\n",
    "(for-loop-header)=\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "227c519f",
   "metadata": {},
   "source": "## For Statement Syntax\n\n`for` loops are usually favored for iteration because the\nall the information about the local loop variable are available in one place at the top,\nwhich helps quickly visualize the overall sequence in the loop.\n\nThe C# for loop statement syntax is:\n\n```csharp\nfor ( *initializer* ; *condition* ; *iterator* )\n{\n// code block (statements)\n}\n```\n\nLet us practice in `csharprepl` or VS Code:"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f91a5d08",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "for (int i = 1; i <= 5; i++)\n",
    "{\n",
    "      Console.WriteLine(i);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7e4fd2a",
   "metadata": {},
   "source": [
    "You can see that the `for` loop has four parts, a three-section semicolon-separated **header**\n",
    "and a **body**:\n",
    "\n",
    "- **Initializer**: This section is a **variable declaration statement** that\n",
    "  declares a `local loop variable` (or `iterator variable` or the counter) and initialize it with an initial value.\n",
    "- **Condition**: The condition section is a **boolean expression** that determines\n",
    "  if the next iteration in the loop should be executed or should the loop be terminated. If it evaluates to true,\n",
    "  the next iteration is executed; otherwise, the loop is exited.\n",
    "- **Iterator**: The iterator (**iteration expression**) section that defines what happens to the counter after each\n",
    "  execution of the body of the loop. A common behavior is reassigning\n",
    "  (increment or decrement) the value of the counter.\n",
    "- The **body** of the loop, which must be a statement or a block of statements.\n",
    "\n",
    "In the example above, the *initializer* is `i = 1`, *condition* is `i <= n`,\n",
    "and *iterator* is `i++` (see {ref}`arithmetic operators <arithmetic-operators>`).\n",
    "\n",
    "Note that the initializer section is executed **only once**, before entering the loop.\n",
    "Also, the declared variable is local to the `for` loop heading and\n",
    "the loop body and can not be accessed from outside the for statement.\n",
    "\n",
    "The two semicolons are always needed in the `for` heading, but any of the\n",
    "parts they normally separate may be omitted.\n",
    "If the condition part is omitted, the condition is\n",
    "interpreted as always true, leading to an infinite loop, that can only\n",
    "terminate due to a `return` or {ref}`break statement <break-continue>` in the body.\n",
    "\n",
    "**Header variation**\n",
    "\n",
    "The declaration of a for loop header is flexible. There may be several variables of the\n",
    "same type initialized, separated by commas. Also, at the end of the `for` loop heading,\n",
    "the iteration portion may include more than one expression, also separated by commas.\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2c491221",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "for (int i = 0, j = 10; i < j; i = i+2, j++) {\n",
    "   Console.WriteLine(\"{0} {1}\", i, j);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "574f50ae",
   "metadata": {},
   "source": "\nGuess what this does, and then paste it into csharprepl to check."
  },
  {
   "cell_type": "markdown",
   "id": "78f606c1",
   "metadata": {},
   "source": "```{index} execution sequence; for loop\n```\n\n### Execution sequence\n\nFor the execution sequence of for loops, note that the different parts of\nthe heading are used at different times:\n\n- When starting the statement, the initialization is done, and then\n  the test of condition (boolean expression).\n- After finishing the body and returning to the heading, the iteration operations\n  are done, followed by the test.\n\n```{index} statement; break and continue\n```\n\n(break-continue)="
  },
  {
   "cell_type": "markdown",
   "id": "b2d46d91",
   "metadata": {},
   "source": "## `break` and `continue` Statements\n\nThe basic syntax of the `for` statement is simplistic. Here we are using the\n`break` and `continue` statements to learn the pragmatic coding practice of the `for`\nloops by connecting to our understanding of conditional/selection statements.\n\nWhen performing iteration, there will be times that you want to alter the code execution\nsequence by skipping part or all of the iterations. If you only want to break out of\nthe *enclosing loop*, but *not* out of the whole method or the outer loop (in case of\nnested looping), use a `break` statement\n\n> `break;`\n\nin place of `return`, since return will break out the current method. With the `break`\nstatement, execution continues after terminating the enclosing iteration statement.\n\nNote that the `break` and `continue` statements only make practical sense\ninside of an `if` statement that is inside the loop. In the following examples,\nyou see a `for` statement with a `break` statement enclosed in a\n`conditional/selection` statement.\n\nAssuming that variable `target` already has a string value and variable `arr` is an array of\nstrings. With your knowledge about `arr.Length` and `arr[i]` from {ref}`string`, read\nthe following code:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b12746bf",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "bool found = false;\n",
    "\n",
    "for (int i = 0; i < arr.Length; i++)   // loop for arr.Length times\n",
    "{\n",
    "   if (arr[i] == target)               // if one of arr == targe\n",
    "   {\n",
    "      found = true;                    // set found to true\n",
    "      break;                           // break out of the enclosing loop\n",
    "   }\n",
    "}\n",
    "\n",
    "if (found)                             // if found == true (from the previous block)\n",
    "{\n",
    "   Console.WriteLine(\"Target found at index \" + i);\n",
    "}\n",
    "else\n",
    "{\n",
    "   Console.WriteLine(\"Target not found\");\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "473cb1ac",
   "metadata": {},
   "source": [
    "\n",
    "When an element in `arr` is reached that matches `target`, execution breaks out\n",
    "of the `for` loop and move on to the `if (found)` statement block below.\n",
    "\n",
    "Now, observe an alternate implementation with a `compound condition` ({ref}`Compound-Boolean-Expressions`) in the heading\n",
    "and no `break` is:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51a2f9b1",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    " bool found = false;\n",
    "\n",
    " for (int i = 0; i < a.Length && !found; i++) {\n",
    "    if (a[i] == target) {\n",
    "       found = true;\n",
    "    }\n",
    " }\n",
    "\n",
    " if (found) {\n",
    "    Console.WriteLine(\"Target found at index \" + i);\n",
    " } else {\n",
    "    Console.WriteLine(\"Target not found\");\n",
    " }\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a800b4de",
   "metadata": {},
   "source": "As you can see, the code exit because the condition section of the if statement header\nhas an expression `!found` ({ref}`logical-operators`), meaning found is not true.\nThe shows that since `break` statements rely on the logic of the conditional statement,\nif the condition can be embedded in the header of the loop, you don't have to use break.\nHowever, if you are designing a loop that has multiple exit criteria, using break statements\ncan make the code much less verbose in the header's condition section, and hence easier to\nfollow because the if statement conditions and the immediate break action may be clearly\npresented."
  },
  {
   "cell_type": "markdown",
   "id": "4aac0740",
   "metadata": {},
   "source": "(nested-for-loop)=\n\n## Nested `for` Loop\n\nThere will be times when **nested** loops are are required for the problem scenario.\nA nested loop can look like this:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b14501fd",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "outer-Loop\n",
    "{\n",
    "   // body of outer-loop\n",
    "   inner-Loop\n",
    "   {\n",
    "      // body of inner-loop\n",
    "   }\n",
    "... ... ...\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61492b12",
   "metadata": {},
   "source": [
    "\n",
    "Continuing with our discussion on `break`, let's say we are in a situation like the following:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "058f2531",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "for (....) {\n",
    "\n",
    "   // some statements of outer for loop\n",
    "\n",
    "   for (....) {\n",
    "      ...\n",
    "      if (...) {\n",
    "      ...\n",
    "      break;\n",
    "      }\n",
    "      ...\n",
    "   }\n",
    "\n",
    "   // some statements of outer for look\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04a94713",
   "metadata": {},
   "source": [
    "\n",
    "The break statement is in the inner loop. If it is reached, the inner loop ends,\n",
    "but the **inner loop** is just a **single statement** inside the outer loop,\n",
    "and **the outer loop continues**.\n",
    "If the outer loop continuation condition remains true,\n",
    "the inner loop will be executed again. As an example:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "83fcc175",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "for (int i = 0; i <= 3; i++)\n",
    "{\n",
    "   for (int j = 0; j <= 3; j++)\n",
    "   {\n",
    "\n",
    "      if (i == 2)\n",
    "      {\n",
    "         break;\n",
    "      }\n",
    "\n",
    "      Console.WriteLine(\"{0} -- {1}\", i, j);\n",
    "   }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27d195f2",
   "metadata": {},
   "source": [
    "\n",
    "Can you determine the output of the preceding code? Try it in `csharprepl` or a test project\n",
    "in your tests folder.\n",
    "\n",
    "`continue` Statement\n",
    "\n",
    "For completeness we mention the much less used `continue` statement:\n",
    "\n",
    "> `continue;`\n",
    "\n",
    "A `continue` statement:\n",
    "\\- does not break out of the whole loop statement.\n",
    "\\- break/skips the execution of the rest of the *body* in the current enclosing loop iteration.\n",
    "\\- starts the next enclosing loop iteration.\n",
    "\n",
    "In the simplest situations, a `continue` statement just avoids an extra `else` clause.\n",
    "It can considerably shorten code if the test is inside of complicated, deeply nested\n",
    "`if` statements. As an example:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81b12c55",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "for (int i = 0; i <= 3; i++)\n",
    "{\n",
    "   for (int j = 0; j <= 3; j++)\n",
    "   {\n",
    "      if (i == 2)\n",
    "      {\n",
    "           continue;\n",
    "      }\n",
    "\n",
    "      Console.WriteLine(\"{0} -- {1}\", i, j);\n",
    "   }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f807ace9",
   "metadata": {},
   "source": [
    "\n",
    "Can you determine the output of the preceding code? Try it in `csharprepl` or a test project\n",
    "in your tests folder."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e0a40e0",
   "metadata": {},
   "source": [
    "## Additional Loop Step Patterns\n",
    "\n",
    "The following examples were moved from `0503-for-examples` to keep all `for` step patterns in one section.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22bd548f",
   "metadata": {},
   "source": "## Step in loop header\n\n`i++` is a common pattern and it increments by 1. Also common in the iterator/step section of\nthe loop header is using assignment statement to control stepping:"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f452acbd",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "i = i + k;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09bb865c",
   "metadata": {},
   "source": [
    "\n",
    "or the equivalent short-hand compound assignment operator:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c80b3a1d",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "i += k;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "259e964b",
   "metadata": {},
   "source": [
    "\n",
    "This means to increment the variable i by k.\n",
    "\n",
    "```{index} operator; compound assignment\n",
    "```\n",
    "\n",
    "Most C# binary operations have a similar variation. For instance\n",
    "if *op* is `+`, `-`, `*`, `/` or `%`,\n",
    "\n",
    "> **variable** *op*= *expression*\n",
    "\n",
    "means the same as\n",
    "\n",
    "> **variable** = **variable** op *expression*\n",
    "\n",
    "For example\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "808a9457",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "x *= 5;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "340541e6",
   "metadata": {},
   "source": [
    "\n",
    "is the same as\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a9d06c5",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "x = x * 5;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2b5fe86",
   "metadata": {},
   "source": "```{index} format; field width and precision\n```\n\n(tables)=\n\n## `foreach` Essentials\n\nThis short section was consolidated from the previous standalone `foreach` page.\n"
  },
  {
   "cell_type": "markdown",
   "id": "f007faa6-0516-4559-9825-2b972805fc86",
   "metadata": {},
   "source": [
    "(foreach-syntax)=\n",
    "\n",
    "# `foreach` Statement\n",
    "\n",
    "```{index} statement; foreach\n",
    "```\n",
    "\n",
    "A C# `foreach` works like a for loop, except it does not use the header\n",
    "(initializer, condition, and iterator) for `conditional` looping flow control. Instead,\n",
    "the `foreach` loop iterates through each element in a given sequence or collection of data and\n",
    "runs a set of instructions once for each of the elements. In other words, the\n",
    "`foreach` loop is used exclusively to loop through elements in an array\n",
    "(or other data sets).\n",
    "\n",
    "In the case of `for` loop in C#, the local loop variable refers to the index of an\n",
    "array whereas, in the case of a `foreach` loop, the loop variable refers to\n",
    "the `values` of the array.\n",
    "\n",
    "In `for` loop, the loop variable is of type `int`. The reason for this is,\n",
    "here the `loop variable` refers to the index position of the array. For the `foreach`\n",
    "loop, the `data type` of the `loop variable` must be the same as the\n",
    "*type of the values stored in the array*. For example, if you have a string array,\n",
    "then the loop variable must be of type string.\n",
    "\n",
    "The syntax of the foreach loop is:\n",
    "\n",
    "    foreach (type variableName in arrayName)\n",
    "    {\n",
    "       // code block to be executed\n",
    "    }\n",
    "\n",
    "A `foreach` statement only works with an object that holds a sequence or collection of data.\n",
    "We will see many more kinds of sequences later. For now we can illustrate\n",
    "with a string, which is a sequence of characters. Observe and test the\n",
    "following two pieces of code in `csharprepl` to see how `foreach`\n",
    "differs from the `for` statement.\n",
    "\n",
    "Say you want to print out some Unicode/ASCII code\n",
    "for certain characters. To achieve that using C# `for` loop, the code could look like:\n",
    "\n",
    "    > string str = \"ABCabc\";\n",
    "    > for (int i = 0; i < 6; i++)\n",
    "      {\n",
    "          Console.WriteLine(\"Unicode for {0} is {1}\", i, (int)str[i]);\n",
    "      }\n",
    "    Unicode for 0 is 65\n",
    "    Unicode for 1 is 66\n",
    "    Unicode for 2 is 67\n",
    "    Unicode for 3 is 97\n",
    "    Unicode for 4 is 98\n",
    "    Unicode for 5 is 99\n",
    "\n",
    "    >\n",
    "\n",
    "As you can see, with a `for` loop, you refer to the individual characters by its index\n",
    "and then cast it to `int`:\n",
    "\n",
    "    (int)str[i]\n",
    "\n",
    "Since strings are considered as arrays consisting of `char` type characters, we can loop\n",
    "through a string using a `foreach` statement using type `char` and *cast* to print out\n",
    "the underlying `int` Unicode value of each character. To achieve the same results using\n",
    "the `foreach` loop, the code would look like the following (pay attention to the local\n",
    "loop variable `char ch`; type is required as usual):\n",
    "\n",
    "    > string str = \"ABCabc\";\n",
    "      foreach (char ch in str) {\n",
    "         Console.WriteLine(\"Unicode for {0} is {1}.\", ch, (int)ch);\n",
    "      }\n",
    "    Unicode for A is 65.\n",
    "    Unicode for B is 66.\n",
    "    Unicode for C is 67.\n",
    "    Unicode for a is 97.\n",
    "    Unicode for b is 98.\n",
    "    Unicode for c is 99.\n",
    "\n",
    "As you can see, in a `foreach` loop, we do not rely on array indexing to refer to the\n",
    "elements. Instead, we refer to the elements directly with the local loop variable (`ch`)\n",
    "declared with the type (`char` in this case).\n",
    "\n",
    "As you see in the preceding example, the `foreach` heading feeds us one\n",
    "character from `str` each time through, using the name `ch`\n",
    "to refer to it. Since any new variable name must be declared with a type in C#,\n",
    "so `ch` is preceded in the heading by its type, `char`. Then we can use\n",
    "`ch` inside the body of the loop.\n",
    "\n",
    "**\\`\\`foreach\\`\\` vs. for loop**\n",
    "\n",
    "Some of the advantages/disadvantages of `foreach` over the `for` loop are:\n",
    "\n",
    "- foreach not involve variable setup (iterates over each element of the array).\n",
    "- foreach are more concise and readable than the indexing `for` statement.\n",
    "\n",
    "The foreach loop does have some limitations: [1]\n",
    "\n",
    "- They don’t keep track of the index of the item.\n",
    "- They cannot iterate backwards. The loop can only go forward in one step.\n",
    "- If you wish to modify the array, the foreach loop isn’t the most suitable option.\n",
    "- The foreach loop cannot execute two-decision statements at once.\n",
    "\n",
    "*If* you have explicit need to refer to the indices of the items in the sequence,\n",
    "then a `foreach` statement does not work for you.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc069029",
   "metadata": {},
   "source": "## `break` in `foreach`\n\nWith a `foreach` loop, which has no explicit continuation condition,\nthe `break` could be more clearly useful. Here is a variant if you do not care\nabout the specific location of the target:\n\n    bool found = false;\n\n    foreach (string s in a) {\n       if (s == target)\n       {\n          found = true;\n          break;\n       }\n    }\n\n    if (found) {\n       Console.WriteLine(\"Target found\");\n    } else {\n       Console.WriteLine(\"Target not found\");\n    }\n\n**Note** that for the for and foreach loops, you could do all the same things\nwith `while` loops, which you will learn in subsequent chapters, but there\nare many situations where `foreach` loops and `for` loops are more convenient\nand easier to read.\n\n`{rubric} Footnotes`\n\n[1] For a discussion of C# for loop vs foreach loop, see\n[Understanding What Is C# Foreach Loop](https://www.simplilearn.com/tutorials/c-sharp-tutorial/c-sharp-foreach)"
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "csharp"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}