casillas
casillas

Reputation: 16803

map high order function format in swift

I am wondering why map format has to be {( )} rather than just { }

func intersect(_ nums1: [Int], _ nums2: [Int]) -> [Int] {

    // the following is right
    var num1Reduce = nums1.reduce(0){ $0 + $ 1}

    /// the following is wrong ??
    var num2Dict = Dictionary(nums2.map{ $0, 1 }, uniquingKeysWith : +)

    // the following is right
    var num1Dict = Dictionary(nums1.map{ ($0, 1) }, uniquingKeysWith : +)

}

and I even see the following format ({ }). I am totally confused!

let cars = peopleArray.map({ $0.cars })
print(cars)

Upvotes: 2

Views: 281

Answers (2)

ali ziwa
ali ziwa

Reputation: 11

A map is a function that takes a closure as a parameter. We can call the map and pass the parameter like we do for any other ordinary function call without removing the brackets ()e.g

(0...100).map ({ _ in print("yeti")})

But swift allows us to remove the brackets as a way of shorthanding and we can write it like, hence eliminating the ()

(0...100).map { _ in print("yeti")}

But incase you want to access individual values of the array elements, you can do so in two ways,

  1. Given an array, you can access it's individual element using $0, which basically says, Hey map, give me the first element at this current index.
(0...100).map {$0}
  1. Instead of using the default swift indexing, you decide to define the value you are accessing by giving it a readable variable name e.g
(0...100).map {element in}

This gets $0 and assigns it to element, the in keyword basically tells the compiler that hey, $0 is now element and we are going to use it after in. Otherwise if you remove the in keyword, the compiler says it doesn't know any variable called element.

For special collections like dictionaries, they have two values per index, i.e the key and value, therefore if you want to access the contents of a dictionary during the mapping, you can do it in two ways like above, a). use the default swift indexes, or give the values per index, readable variable names. e.g

let dictionary = ["a": 3, "b": 4, "c": 5]
dictionary.map{($0, $1)}

We use inner brackets () to let the compiler know that the collection we are mapping over has two values per index. Please note the inner parenthesis are creating a tuple

dictionary.map {(key, value) in }

Upvotes: 1

rmaddy
rmaddy

Reputation: 318834

You are using the following Dictionary initializer:

init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Dictionary<Key, Value>.Value, Dictionary<Key, Value>.Value) throws -> Dictionary<Key, Value>.Value) rethrows where S : Sequence, S.Element == (Key, Value)

Note that S is a sequence where its elements are a tuple of key/value pairs.

When you pass nums1.map{ ($0, 1) } to the first parameter, you are creating an array of key/value tuples from nums1.

It fails when you use nums2.map{ $0, 1 } because that is missing the parentheses for the tuple.

Keep in mind that nums1.map{ ($0, 1) } is shorthand for nums1.map({ ($0, 1) }). That's all related to trailing closures which has nothing to do with the parentheses for the tuple that appear inside the { }.

Upvotes: 1

Related Questions