title: How to recursively compare two Codable objects and get differences in Swift?
body: <p>I have two instances of <code>Lecture</code> which are  <code>oldLecture</code> and <code>newLecture</code>. A simplified declaration of <code>Lecture</code> is as follows (the full version has many more fields):</p>
  <pre class="lang-swift prettyprint-override"><code>struct Lecture: Codable {
      let title: String
      let class_times: [ClassTime]
      let color: [String: String]
  }
  
  struct ClassTime: Codable {
      let start: Double
      let len: Double
  }
  </code></pre>
  <p>Now I need to <em>recursively</em> compare <code>oldLecture</code> and <code>newLecture</code>, and create a new dictionary-like object that contains <em>only</em> the properties that are modified in <code>newLecture</code>. The resulting object will be sent to the server as <code>PUT</code> request.</p>
  <p>For example,</p>
  <pre class="lang-swift prettyprint-override"><code>var oldLecture = Lecture(title: &quot;lecture1&quot;, 
                           class_times: [ClassTime(start: 1, len: 2)], 
                           color: [&quot;fg&quot;: &quot;#fff&quot;, &quot;bg&quot;: &quot;#000&quot;])
  var newLecture = Lecture(title: &quot;lecture1&quot;, 
                           class_times: [ClassTime(start: 2, len: 3)], 
                           color: [&quot;fg&quot;: &quot;#fff&quot;, &quot;bg&quot;: &quot;#000&quot;])
  
  // the result object should only contain `class_times` key with the value of `[ClassTime(start: 2, len: 3)]`
  </code></pre>
  <h2>What I have tried so far</h2>
  <pre class="lang-swift prettyprint-override"><code>guard let oldDict = oldLecture.asDictionary() else { return nil }
  guard let newDict = newLecture.asDictionary() else { return nil }
  var dict: [String: Any] = [:]
  for (key, newVal) in newDict {
      if let oldVal = oldDict[key], oldVal != newVal {
          dict[key] = newVal
      }
  }
  </code></pre>
  <p>The approach above won't work because it doesn't compare <code>oldVal</code> and <code>newVal</code> recursively.</p>
  <p>Is there a cleaner way to achieve this, without using third-party libraries such as <code>SwiftyJSON</code>?</p>