Swift enumerate functions. How does it work behind?
It works because in addition to array having a map
method, there is a map
function that takes any kind of SequenceType
:
func map<S : SequenceType, T>(source: S, transform: (S.Generator.Element) -> T) -> [T]
This works not just with arrays, but any kind of sequence – strings, ranges, zipped pairs of sequences, and the result of enumerate
, which is also a sequence:
// enumerate is a function that takes any kind of sequence, and returns
// an EnumerateSequence object
func enumerate<Seq : SequenceType>(base: Seq) -> EnumerateSequence<Seq>
EnumerateSequence
is a type that holds on to another sequence (in your case, the array [1,2,3]
) and then when asked to generate an element, generates the next element from it’s contained sequence along with an incrementing number.
What is the purpose of .enumerated() and .map() in this code?
- Map is used for modifications. At this point you are basically initialising an object of
Result
by givingresults
array as a param to it:
results.map {
return Result(dictionary: $0)
}
$0
means the first input. In a following case, $0
is equal to param
(we just gave it a name):
results.map { param in
return Result(dictionary: param)
}
.enumerated()
returns each element of an array with its index number. Without it you would have only the element like this:
.map({ (element) -> Result in
// you don't have `index` value inside the closure anymore
// element.rank = index + 1
return element
})
Note that the element
in the closure above is the same Result(dictionary: $0)
object that you created in a previous map
function.
- At the end, you are making and modification by assigning elements index number increased by 1 to the element's
rank
property, and returning it:
.map({ (index, element) -> Result in
// element.rank = index + 1
return element
})
Note that the value we get after the 3rd step, including all modification is assigned to let itunesResults
.
enumerate function in Swift
fontNamesForFamilyName()
returns AnyObject[]!, which can't be directly enumerated. You have explicitly type your fontNames array.
let fontNames: Array = UIFont.fontNamesForFamilyName(familyName)
for (index, value : AnyObject) in enumerate(fontNames) {
println(value)
}
And as @Van Du Tran pointed out in the comments below, the syntax for enumerate has changed in Swift 2. Now you can use the following.
let fontNames: Array = UIFont.fontNamesForFamilyName(familyName)
for (index, value) in fontNames.enumerate() {
print(value)
}
It's also worth noting that since fontNamesForFamilyName
now uses an Objective C generic type, it returns [String]
so no conversion from AnyObject
is needed.
Enumeration behaviour understanding (Intro to App Development with Swift - Lesson 19)
Your instructions say "so that the final else statement is called". That would be the soup return, not the "how did we get here" return. As you say, with 3 lunch choices and 3 if/else statements, one of them will always be invoked. You have to add a 4th lunch choice that doesn't have a corresponding if or else if in order for the "how did we get here" code to execute.
How to iterate a loop with index and element in Swift
Yes. As of Swift 3.0, if you need the index for each element along with its value, you can use the enumerated()
method to iterate over the array. It returns a sequence of pairs composed of the index and the value for each item in the array. For example:
for (index, element) in list.enumerated() {
print("Item \(index): \(element)")
}
Before Swift 3.0 and after Swift 2.0, the function was called enumerate()
:
for (index, element) in list.enumerate() {
print("Item \(index): \(element)")
}
Prior to Swift 2.0, enumerate
was a global function.
for (index, element) in enumerate(list) {
println("Item \(index): \(element)")
}
Function with different parameters
Here is a solution based on the one linked to in the question
protocol OneOrManyInt { }
extension Int: OneOrManyInt { }
extension Array: OneOrManyInt where Element == Int {}
func add(x : Float, y : Float, z : Float, out : OneOrManyInt? = nil, incoming : OneOrManyInt? = nil) -> Bool {...}
and then it can be used like this for instance
add(x: 1.0, y: 2.0, z: 3.0, out: [1,2,3], incoming: 10)
add(x: 1.0, y: 2.0, z: 3.0, incoming: 10)
add(x: 1.0, y: 2.0, z: 3.0, out: [1,2,3])
unable to find enumerate() func in Swift standard library reference
When you encounter a Swift standard library function or method that you can't find documentation on, command-click on it in Xcode. That will take you to its definition, which in this case is
extension SequenceType {
/// Return a lazy `SequenceType` containing pairs (*n*, *x*), where
/// *n*s are consecutive `Int`s starting at zero, and *x*s are
/// the elements of `base`:
///
/// > for (n, c) in "Swift".characters.enumerate() {
/// print("\(n): '\(c)'")
/// }
/// 0: 'S'
/// 1: 'w'
/// 2: 'i'
/// 3: 'f'
/// 4: 't'
@warn_unused_result
public func enumerate() -> EnumerateSequence<Self>
}
What the above states is that enumerate()
gives you back a tuple for each value in your collection, with the first element in the tuple being the index of the current item and the second being the value of that item.
What is the purpose of the word let inside a catch expression?
It is a “value binding pattern” (inside an “enumeration case pattern”).
SandwichError
is an enumeration with “associated values”, something like
enum SandwichError: Error {
case outOfCleanDishes
case missingIngredients([String])
}
Each catch
keyword is followed by a pattern, and if an SandwichError.missingIngredients
error is thrown with
throw SandwichError.missingIngredients(["Salt", "Pepper"])
then
catch SandwichError.missingIngredients(let ingredients)
matches and the local variable ingredients
is bound to the associated value ["Salt", "Pepper"]
for the catch block.
It works essentially as for Matching Enumeration Values with a Switch Statement:
You can check the different barcode types using a switch statement, similar to the example in Matching Enumeration Values with a Switch Statement. This time, however, the associated values are extracted as part of the switch statement. You extract each associated value as a constant (with the let prefix) or a variable (with the var prefix) for use within the switch case’s body
Related Topics
Textfield Delegate Shouldchangecharactersinrange
How to Insert a Sublayer in Swift
How to Detect Text View Begin Editing and End Editing in Swift 3
Textfield in Swiftui Loses Focus When I Enter a Character
Generic Within a Generic in Swift
Swift Error with Generic Array
Swiftui Button Interact with Map
Passing Property Type as Parameter
Mutually Recursive Generic Enums
Swift 3 - Pass Struct by Reference via Unsafemutablerawpointer
How to Use the "Handler" of Uialertaction to Call Another Uialertaction
Swift Struct with Lazy, Private Property Conforming to Protocol
Xcframework Issue, a Library with the Identifier "Ios-Armv7_Arm64" Already Exists
Swift- How to Display Image Over Button
Uibezierpath Appending Overlapping Isn't Filled
Swift 3 Type Inference Confusion
Avaudiosinknode with Non-Default, But Still Device-Native Sample Rates