Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2.0 flatMap usage

Tags:

swift

I was reading the code contained in a file produced as a tutorial by Apple ("Auto Layout Cookbook"), when I found the following lines:

let recipies: [Recipe] = fileContents.flatMap { recipeData in
            // Fetch the recipe information.
            guard let title = recipeData["Title"],
                descriptionFileName = recipeData["Document"],
                identifierString = recipeData["Identifier"] else {
                    assertionFailure("Unable to fetch recipe information.")
                    return nil
            }

            // Convert the identifier string to an `Identifier` type.
            guard let identifier = CookbookStoryboardIdentifier(rawValue: identifierString) else {
                assertionFailure("Invalid recipe identifier: \(identifierString).")
                return nil
            }

            // Read the recipe description from the associated file.
            var description: String
            do {
                guard let descriptionURL = bundle.URLForResource(descriptionFileName, withExtension: nil) else {
                    fatalError("Unable to determine recipe description URL from fileName: \(descriptionFileName).")
                }

                try description = NSString(contentsOfURL: descriptionURL, encoding: NSUTF8StringEncoding) as String
            }
            catch {
                fatalError("Unable to read recipe description from file")
            }
            return Recipe(title: title, identifier: identifier, description: description)
        }

I red the docs and found, if I understand well, you use flatMap basicly when you need to transform the contents of a bidimensional array into a linear array.

If so, I don't understand:

  1. what recipeData in does: I suppose it is just like a foreach;
  2. why this code returns each Recipe (Recipe is a struct);
  3. why they use flatMap (what are they flattening?);

Any help, tips and (why not?) tomatoes is appreciated.


1 Answers

flatMap will also remove the nil values, which is a bit weird if you have used Haskell (for example).

let foo: [String] = ["1","3","5","asd","3"]

let bar: [Int] = foo.flatMap { val in

    guard let int = Int(val) else { return nil}
    return int
}

// bar == [1,3,5,3]

Answering your questions:

what recipeData in does: I suppose it is just like a foreach;

A forEach takes a function: T -> Void, which is a bit different from what's happening there. You basically have an [AnyObject] and you are converting it to [Recipe].

why they use flatMap (what are they flattening?);

Going back to my initial explanation, from the snippet I would say they are removing the nil Recipes, so you only have the Recipes you were able to create.

like image 95
Rui Peres Avatar answered Feb 24 '26 12:02

Rui Peres



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!