2

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)
casillas
  • 16,351
  • 19
  • 115
  • 215
  • The `( )` is creating a tuple. See the documentation for the `Dictionary` initializer that you are using. – rmaddy Feb 25 '19 at 05:47
  • @rmaddy, any useful url as a reference? – casillas Feb 25 '19 at 05:49
  • 1
    I explain every syntactic sugar for closures (apart from capture expressions) in [this answer](https://stackoverflow.com/a/40390414/3141234). It takes it from verbose to Swifty, step by step. It's worth checking out! – Alexander Feb 25 '19 at 06:23

2 Answers2

1

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 { }.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
1

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 }
ali ziwa
  • 11
  • 4