title: Can I conform to Hashable using different properties than used to conform to Equatable?
body: <p>How can I have an object have the same hash value but not equate?</p>
  <pre><code>~pseudo~
  
  savedObj = { id: 123, status: &quot;good&quot; }
  objects = Set&lt;myType&gt;()
  
  incomingObj = { id: 123, status: &quot;bad&quot; }
  
  // savedObj should not equal incomingObj but
  // Should update 123 and not insert a new object
  objects.update(incomingObj)
  </code></pre>
  <p>Here's some more proper code to dig in to this. I'm new to Swift so feel I'm just not understanding things properly.</p>
  <p>Let's say I have a bunch of IoT wifi devices I want to scan for. They each have a unique MAC address and variable (hypothetical) status. I want to add these devices to a Set and to be able to compare a current scan against the existing Set.</p>
  <pre><code>struct Device: Hashable {
    let macAddress: String
    var status: String?
  
    init(mac: String) {
      macAddress = mac
    }
  </code></pre>
  <p>To make the devices in the Set unique, I'll use the mac address, but since the status can vary, I don't want that taken into account. So I add the following code:</p>
  <pre><code>...
    func hash(into hasher: inout Hasher) {
      hasher.combine(macAddress)
    }
  </code></pre>
  <p>This is where I get confused and need help. If I add <code>device1</code> and <code>device2</code> to my set and then update the status on <code>device1</code> to &quot;ready&quot; it will be a new, third, entry into the set. I've discovered to make sure this doesn't happen I have to conform to Equatable manually:</p>
  <pre><code>...
    static func == (lhs: Device, rhs: Device) -&gt; Bool {
      return
        lhs.macAddress == rhs.macAddress
    }
  </code></pre>
  <p>But that means that if I have a device in my set with no status and the mac address <code>device1</code> it would equal a secondary scan of <code>device1</code> with a status set to &quot;ready&quot; because I am only equating the <code>macAddress</code>. Is there any way around that? I want to insert into the set uniquely based on <code>macAddress</code> but equate based on all properties of the struct.</p>
  <p>EDIT:
  I've seen something like this statement in other SO answers, which is part of why I'm confused my code doesn't work:
  &quot;Two objects that are equal will have the same hash value, but two objects with the same hash value are not necessarily equal.&quot;</p>
  <p>Yet I can't make the code prove that.</p>