title: How to deep merge 2 Swift dictionaries
body: <p>My question is simple, I want to know how to do a deep merge of 2 Swift dictionaries (not NSDictionary).</p>
  
  <pre><code>let dict1 = [
      "a": 1,
      "b": 2,
      "c": [
          "d": 3
      ],
      "f": 2
  ]
  
  let dict2 = [
      "b": 4,
      "c": [
          "e": 5
      ],
      "f": ["g": 6]
  ]
  
  let dict3 = dict1.merge(dict2)
  
  /* Expected:
  
  dict3 = [
      "a": 1,
      "b": 4,
      "c": [
          "d": 3,
          "e": 5
      ],
      "f": ["g": 6]
  ]
  
  */
  </code></pre>
  
  <p>When <code>dict1</code> and <code>dict2</code> have the same key, I expect the value to be replaced, but if that value is another dictionary, I expect it to be merged recursively.</p>
  
  <p>Here is the solution I'd like:</p>
  
  <pre><code>protocol Mergeable {
  
      mutating func merge(obj: Self)
  
  }
  
  extension Dictionary: Mergeable {
  
      // if they have the same key, the new value is taken
      mutating func merge(dictionary: Dictionary) {
          for (key, value) in dictionary {
              let oldValue = self[key]
  
              if oldValue is Mergeable &amp;&amp; value is Mergeable {
                  var oldValue = oldValue as! Mergeable
                  let newValue = value as! Mergeable
  
                  oldValue.merge(newValue)
  
                  self[key] = oldValue
              } else {
                  self[key] = value
              }
          }
      }
  
  }
  </code></pre>
  
  <p>but it gives me the error <code>Protocol 'Mergeable' can only be used as a generic constraint because it has Self or associated type requirements</code></p>
  
  <p><strong>EDIT:</strong>
  My question is different from <a href="https://stackoverflow.com/questions/26728477/swift-how-to-combine-two-dictionary-arrays">Swift: how to combine two Dictionary instances?</a> because that one is not a deep merge.</p>
  
  <p>With that solution, it would produce:</p>
  
  <pre><code>dict3 = [
      "a": 1,
      "b": 4,
      "c": [
          "e": 5
      ]
  ]
  </code></pre>