# flatMap Method in Action — Swift 3

In this time we’re going to talk about the `flatMap` method.

But first let’s put in context.

Let’s say we have an array of arrays:

``var arrayOfArrays = [ [1, 1], [2, 2], [3, 3] ]``

and there is a challenge about multiplying by 2 its content and the result should look like this:

`// [ [2, 2], [4, 4], [6, 6] ]`

One approach to solve this challenge could be using the `map` Array's method two times like this:

`// first iterating the array of arraysarrayOfArrays.map { array in    // and second iterating   // the current array  return array.map { integer in    // multiplying its content by 2    return integer * 2  }`
`} // [ [2, 2], [4, 4], [6, 6] ]`

Good, then there is a new challenge converting the multiplied array of arrays to only one array like this:

`// [ 2, 2, 4, 4, 6, 6 ]`

Fortunately `Array`’s structure has a method for this purpose that’s called `joined`, let's use it:

`var multipliedByTwo = arrayOfArrays.map { array in   return array.map { integer in     return integer * 2   }}`
`var flattened = Array(multipliedByTwo.joined())print(flattened) // outputs: [ 2, 2, 4, 4, 6, 6 ]`

But actually `Array`’s structure has already a method that does these two things at the same time, mapping and flattening, yes that’s `flatMap`:

`var arrayOfArrays = [ [1, 1], [2, 2], [3, 3] ]`
`var flattenedArray = arrayOfArrays.flatMap { array in  return array.map { integer in    return integer * 2  }}`
`print(flattenedArray) // outputs: [ 2, 2, 4, 4, 6, 6 ]`

Let’s see another example.

In fact if we were iterating an array, `flatMap` and `map` would behave similarly:

`let numbers: [Int] = [1, 2, 3]`
`let numbersMap = numbers.map { return \$0 }print(numbersMap) // [1, 2, 3]`
`let numbersFlatMap = numbers.flatMap { return \$0 }print(numbersFlatMap) // [1, 2, 3]`

But if we had an array of optionals, there would be a big difference:

`let numbers: [Int?] = [1, nil, 3]`
`let numbersMap = numbers.map { return \$0 }print(numbersMap) // [Optional(1), nil, Optional(3)]`
`let numbersFlatMap = numbers.flatMap { return \$0 }print(numbersFlatMap) // [1, 3]`

while map method practically doesn’t change anything on the `numbersMap` array result, `flatMap` does two things: first convert item’s type from `Int?` to `Int` and then removes the `nil` items on the resulting conversion `numbersFlatMap,` pretty neat.

Now let’s finish with a practical use of `flatMap` in the real world:

Let’s say we have a method called `getJSON` which based on a url will get us an array of dictionaries from a server:

`let url = "https://jsonplaceholder.typicode.com/users"`
`getJSON(from: url) { (dictionaries: [Dictionary<String, Any>]?) in  print(dictionaries)  // outputs:   //  Optional([   //    ["name": Leanne Graham, "id": 1],   //    [..],   //  ])}`

So we create a `User` structure to store this data:

`struct User {`
`  let id: Int  let name: String  let username: String`
`  init?(dictionary: Dictionary<String: Any>) {    guard       let id = dictionary[“id”] as? Int,      let name = dictionary[“name”] as? String,      let username = dictionary[“username”] as? String    else {      return nil    }`
`    self.id = id    self.name = name    self.username = username  }`
`}`

A classical approach to convert the data in an `array` of `User `type could be something like this:

`getJSON(from: url) { (dictionaries: [Dictionary<String, Any>]?) in  if let dictionaries = dictionaries {    var users = [User]()`
`    for dictionary in dictionaries {      let user = User(dictionary: dictionary)            if let user = user {        users.append(user)      }    }`
`    print(users)     // [ User(id: 1, name: "Leanne Graham", username: "Bret"), .. ]`
`  }}`

Bear in mind that when are creating a new `User` passing a`dictionary`, it is possible that it could fail the initializaton and return a `nil` since we declared the `init` as a failable one.

`struct User {  // some code`
`  // failable initalizer  init?(dictionary: Dictionary<String: Any>) {    // some code  }}`

That’s why we verify that user is not `nil` before adding to the `users` array.

But there is another approach iterating the dictionaries using flatMap:

`getJSON(from: url) { (dictionaries: [Dictionary<String, Any>]?) in  if let dictionaries = dictionaries {    var users = [User]()`
`    // Accepts a dictionary and return a User?    let closure: (Dictionary<String, Any>) -> User?`
`    // Initializing the closure    closure = { dictionary in      return User(dictionary: dictionary)    }`
`    users = dictionaries.flatMap(closure)`
`    print(users)     // [ User(id: 1, name: "Leanne Graham", username: "Bret"), .. ]`
`  }}`

So `flatMap `will do three things:

1. Of course iterate the `dictionaries` array to convert an array of `User `type
2. if a User is created without any issue , `flatMap` converts from `User?` to `User` type every element.
3. it filters the `nil` values because failable initializers (`init?)` could return nil

After`flatMap `finishes, we have an array of `[User]`.

To finish we can reduce the code even more, like this:

`getJSON(from: url) { (dictionaries: [Dictionary<String, Any>]?) in  if let dictionaries = dictionaries {    var users = [User]()`
`    users = dictionaries.flatMap(User.init)`
`    print(users)     // [ User(id: 1, name: "Leanne Graham", username: "Bret"), .. ]`
`  }}`

if you see the code where we used a closure, its type was this:

`let closure: (Dictionary<String, Any>) -> User?`
`// code`
`users = dictionaries.flatMap(closure)`

Expects a Dictionary<String, Any> as an argument and returns a User?

And if you see the initializer function of the User struct:

`init?(dictionary: Dictionary<String: Any>) {    // some code}`

Expect a Dictionary<String, Any> as an argument and of course its`init?` function call will return a `User?`

So that’s why we passed `User.init` (which refers to `User` structure’s init function) to `flatMap`:

`users = dictionaries.flatMap(User.init)`

We saw various examples of using `flatMap` method but some important points to remember are:

• when working with array of arrays, applying `flatMap` will do two things, mapping and flattening.
• when working with arrays of optional types, `flatMap` will map, convert the optional types to non optional, and remove the nil values.