Swift Enumerate Functions. How Does It Work Behind

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?

  1. Map is used for modifications. At this point you are basically initialising an object of Result by giving results 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)
}

  1. .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.


  1. 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



Leave a reply



Submit