diff --git a/concepts/for-loops/.meta/config.json b/concepts/for-loops/.meta/config.json index d5cb6a257..1d255acef 100644 --- a/concepts/for-loops/.meta/config.json +++ b/concepts/for-loops/.meta/config.json @@ -1,7 +1,8 @@ { "blurb": "For loops can be used to iterate over a sequence of values.", "authors": [ - "wneumann" + "wneumann", + "meatball133" ], "contributors": [] } diff --git a/concepts/for-loops/about.md b/concepts/for-loops/about.md index e69de29bb..2dcdc3854 100644 --- a/concepts/for-loops/about.md +++ b/concepts/for-loops/about.md @@ -0,0 +1,120 @@ +# For loops + +Looping is a fundamental concept in programming that allows you to execute a block of code multiple times. +In Swift, there are two types of loops: [`for-in` loops][for-loops] and `while` loops. +In this chapter, you'll learn about `for-in` loops. + +For loops allows you to iterate over a sequence of values, taking each element in turn, binding it to a variable of your choosing. +Swift allows you to iterate over a variety of sequences, such as ranges, arrays, and strings (and more types which will be covered later). +When every element of the sequence has been iterated over, the loop exits. + +For loops are declared by using the `for` keyword, followed by a variable name, the `in` keyword, and a sequence of values to iterate over. +The variable given in the `for-in` loop is inmutable, meaning you can't change its value inside the loop. +Here's an example of a `for-in` loop that iterates over an array of numbers: + +```swift +let numbers = [3, 10, 7, 11] + +for number in numbers { + print(number) +} +print("Done with numbers") + +// prints: +// 3 +// 10 +// 7 +// 11 +// Done with numbers +``` + +~~~~exercism/note +The `number` variable is declared in the `for-in` loop and is only available within the loop's scope. + +```swift +let numbers = [3, 10, 7, 11] + +for number in numbers { + number + 1 +} +number + 1 // Error: Use of unresolved identifier 'number' +``` +~~~~ + +## Iterating over a range + +You can also iterate over a range of numbers using a `for-in` loop. +This allows you to execute a block of code a specific number of times, for example, the range `1...5` will iterate over the numbers 1, 2, 3, 4, and 5, so the loop will execute 5 times. +Sometimes you might want to iterate over indexes, in a datastructure like an array, then you can use a `0.. ReturnType in bodyOfClosure }` +- Refer to the exercise introduction for an example how to use a for loop to iterate over a slice. +- Use a helper variable to store the total count and increase that variable as you go through the slice. +- Think about the correct initial value for that helper variable. -## 1. Write a closure to flip two wires +## 2. Calculate the number of visiting birds in a specific week -- You can use tuple decomposition to name the individual components of a tuple +- This task is similar to the first one, you can copy your code as a starting point. +- Think about which indexes in the slice you would need to take into account for week number 1 and 2, respectively. +- Now find a general way to calculate the first and the last index that should be considered. +- With that you can set up the for loop to only iterate over the relevant section of the slice. -## 2. Write a closure to rotate the wires +## 3. Fix a counting mistake -- You can use tuple decomposition to name the individual components of a tuple - -## 3. Implement a wire shuffle generator - -- You can return the last bit of a number, `n`, by computing `n % 2` -- You can remove the last bit of a number, `n`, by computing `n / 2` -- You need to make variable copies of function and closure parameters if you want to mutate them. +- Again you need to set up a for loop to iterate over the whole bird count slice. +- This time you only need to visit every second entry in the slice. +- Change the step so the counter variable is increased accordingly after each iteration. +- In the body of the for loop you can use the increment operator to change the value of an element in a slice in-place. diff --git a/exercises/concept/bird-watcher/.docs/introduction.md b/exercises/concept/bird-watcher/.docs/introduction.md index 2f258f19b..07c6622e5 100644 --- a/exercises/concept/bird-watcher/.docs/introduction.md +++ b/exercises/concept/bird-watcher/.docs/introduction.md @@ -1,51 +1,108 @@ -# Introduction +# For loops -Closures in Swift are self-contained blocks of code that can be passed parameters to trigger their computation and return values. Closures also capture values from their environment and use them in their computations. As they are self contained, they may be passed around in a program like other values or assigned to constants and variables. +Looping is a fundamental concept in programming that allows you to execute a block of code multiple times. +In Swift, there are two types of loops: [`for-in` loops][for-loops] and `while` loops. +In this chapter, you'll learn about `for-in` loops. -Closures may sound a lot like Swift functions; they do, and for good reason. Functions in swift are just special cases of closures which are required to have a name and are defined using a slightly different syntax. +For loops allows you to iterate over a sequence of values, taking each element in turn, binding it to a variable of your choosing. +Swift allows you to iterate over a variety of sequences, such as ranges, arrays, and strings (and more types which will be covered later). +When every element of the sequence has been iterated over, the loop exits. -While functions in Swift are technically closures, when people refer to "closures" in Swift, they are referring to [closure expressions][closure-expressions]. Closure expressions are written as a parameter list followed by a return type and the keyword `in` followed by the body of the closure, all contained in a pair of curly braces: +For loops are declared by using the `for` keyword, followed by a variable name, the `in` keyword, and a sequence of values to iterate over. +The variable given in the `for-in` loop is inmutable, meaning you can't change its value inside the loop. +Here's an example of a `for-in` loop that iterates over an array of numbers: ```swift -{ (a: Double, b: Double) -> Double in - return a + b / 2.0 +let numbers = [3, 10, 7, 11] + +for number in numbers { + print(number) } +print("Done with numbers") + +// prints: +// 3 +// 10 +// 7 +// 11 +// Done with numbers ``` -This defines a closure expression of type `(Double, Double) -> Double`, and it can be executed in a similar manner to a function of this type, by applying it to parameters of the appropriate type: +~~~~exercism/note +The `number` variable is declared in the `for-in` loop and is only available within the loop's scope. ```swift -{ (a: Double, b: Double) -> Double in - return a + b / 2.0 -}(10.0, 15.0) -// => 12.5 +let numbers = [3, 10, 7, 11] + +for number in numbers { + number + 1 +} +number + 1 // Error: Use of unresolved identifier 'number' ``` +~~~~ -As it's not very convenient to write out the full closure expression every time one wants to execute it, closures can be assigned to names, like any other value in Swift. They can then be called by applying the name to the parameters: +## Iterating over a range + +You can also iterate over a range of numbers using a `for-in` loop. +This allows you to execute a block of code a specific number of times, for example, the range `1...5` will iterate over the numbers 1, 2, 3, 4, and 5, so the loop will execute 5 times. +Sometimes you might want to iterate over indexes, in a datastructure like an array, then you can use a `0.. Double in - a + b / 2.0 +let numbers = [3, 10, 7, 11] + +for i in 0.. 56.5 +// prints: +// 3 +// 10 +// 7 +// 11 ``` -As seen above, closures, like regular functions, may omit the `return` keyword if the body of the closure is a single expression. +## Iterating over a string -Most often, closures are used with higher-order functions, either passed in as parameters or returned as results: +You can also iterate over a string using a `for-in` loop. +This allows you to iterate over each character in the string, and note specifically that the type given in the loop is a `Character`. ```swift -[11, 75, 3, 99, 53].contains(where: { (x: Int) -> Bool in x > 100 }) -// => false +let message = "Hello!" + +for character in message { + print(character) +} + +// prints: +// H +// e +// l +// l +// o +// ! +``` + +## stride -["apple", "ball", "carrot"].sorted(by: { (s1: String, s2: String) -> Bool in s1.count < s2.count }) -// => ["ball", "apple", "carrot"] +Swift also provides a `stride` function that allows you to create a sequence over a range with a specific step. +Which can be then iterated over using a `for-in` loop. +`stride` is defined as [`stride(from:to:by:)`][stride-to] or [`stride(from:through:by:)`][stride-through], the first one is exclusive and the second one is inclusive. -func makeAdder(base: Int) -> (Int) -> Int { - { (x: Int) -> Int in base + x } +```swift +for i in stride(from: 0, to: 10, by: 2) { + print(i) } + +// prints: +// 0 +// 2 +// 4 +// 6 +// 8 ``` -[closure-expressions]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/#Closure-Expressions +Note that the `to` parameter is exclusive, so the loop will iterate until the number before the `to` parameter, while the `through` parameter is inclusive, so in this case it would also include the `10`. + +[stride-to]: https://developer.apple.com/documentation/swift/stride(from:to:by:) +[stride-through]: https://developer.apple.com/documentation/swift/stride(from:through:by:) +[for-loops]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/controlflow/#For-In-Loops