# Equality in Set in Swift

**URL:** <https://forums.swift.org/t/equality-in-set-in-swift/80246>\
**Category:** Using Swift\
**Tags:** equatable, set\
**Created:** [June 2, 2025, 10:41am UTC](https://forums.swift.org/t/equality-in-set-in-swift/80246 "2025-06-02T10:41:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![supermage](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/supermage/32/45033_2.png) [@supermage](https://forums.swift.org/u/supermage)\
**Post date:** [June 2, 2025, 10:41am UTC](https://forums.swift.org/t/equality-in-set-in-swift/80246/1 "2025-06-02T10:41:31Z")

</div>

I have a type called `FeildType` which is `Equatable` , `Hashable`, `Identifiable`.  
I use a type called `UniqueID` as my identifier which is defined as below:

```swift
public struct UniqueID: Hashable , Equatable , Sendable {
    
    public let fullName : String
    
    public let parentName : String
    
    public var id : String { parentName + "." + fullName }
    
  public static func == (lhs: UniqueID, rhs: UniqueID) -> Bool {
        return rhs.id == lhs.id
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
}

```

and `FeildType` implemention is like this:

```swift
public final class FeildType : Identifiable , Hashable , Equatable {
   

    /// id used for Hashable , Equatable
    public var id : UniqueID { .init(fullName: fullName, parentName: parentType?.fullName ?? "" ) }
    //....
}
public extension FeildType{
    static func == (lhs: FeildType , rhs: FeildType) -> Bool {
        lhs.id == rhs.id
    }
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

```

Now I compare 2 `Set<FeildType>` s in my test case swift **sometimes** returns false even-though 2 sets have elements with identical `id`s:

```swift
 #expect(optionalInfo.fields.map(\.id).ascending() 
           == person.fields.map(\.id).ascending() ) //Always True

// Note: person.fields and optionalInfo.fields are not arrays, they are Set<FeildType>
 #expect(optionalInfo.fields == person.fields) // Most of the times False

```

the questions is why? and more importantly why **sometimes** it fails and sometimes it doesn't?

---

<div class="post-metadata">

**Author:** ![sveinhal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sveinhal/32/3992_2.png) [@sveinhal](https://forums.swift.org/u/sveinhal)\
**Post date:** [June 2, 2025, 11:41am UTC](https://forums.swift.org/t/equality-in-set-in-swift/80246/2 "2025-06-02T11:41:13Z")

</div>

Your `FeildType` is a class. Can its `id` mutate during its lifetime? If so, you're breaking the contract with `Set`. You shouldn’t change the hash value of an element in a set (or a `Dictionary`) while it is in the set.

---

<div class="post-metadata">

**Author:** ![supermage](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/supermage/32/45033_2.png) [@supermage](https://forums.swift.org/u/supermage)\
**Post date:** [June 2, 2025, 4:57pm UTC](https://forums.swift.org/t/equality-in-set-in-swift/80246/3 "2025-06-02T16:57:03Z")

</div>

Yes , `id` can mutate and in fact that's intentional. So I will just dont use Set then.  
Thanks 🙏

---

<div class="post-metadata">

**Author:** ![AlexanderM](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alexanderm/32/9781_2.png) [@AlexanderM](https://forums.swift.org/u/AlexanderM)\
**Post date:** [June 2, 2025, 5:20pm UTC](https://forums.swift.org/t/equality-in-set-in-swift/80246/4 "2025-06-02T17:20:45Z")

</div>

As a cautionary note: systems are much simpler when IDs are immutable.

One time, I was building a CRUD web app for managing student enrolments. The institution's student IDs seems like a natural choice for a primary key, but that actually turned out to be a total pain. If someone maybe a typo in the student ID field, they couldn't edit it without deleting that record and creating a "new" one under the correct ID.

Adding a separate UUID for internal use ended up greatly simplifying the whole rest of the system.

---

<div class="post-metadata">

**Author:** ![supermage](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/supermage/32/45033_2.png) [@supermage](https://forums.swift.org/u/supermage)\
**Post date:** [June 2, 2025, 6:02pm UTC](https://forums.swift.org/t/equality-in-set-in-swift/80246/5 "2025-06-02T18:02:05Z")

</div>

I am trying to make an open source library to operate on top of SwiftSyntax in order to extract information from swift source code. I also want to add some limited type inference in it. ☺

Since in Swift you don't need to code in-order ( unlike C for example that you have to define your type before creating variable of it), I need `id` of my objects to update over time ( as I gather more information later on) and that's the main reason I am using `class` instead of `struct` cause sharing data is actually intended here.

While I totaly agree with you , in fact I was using `UUID` at first , but it makes the problem much harder to deal with. I ended up with creating my own `UniqueArray` array type 😀
