Skip to content

Instantly share code, notes, and snippets.

@DanielCardonaRojas
Created February 19, 2026 18:48
Show Gist options
  • Select an option

  • Save DanielCardonaRojas/c2d7ff8cf69cb3af473f417e132d8a7d to your computer and use it in GitHub Desktop.

Select an option

Save DanielCardonaRojas/c2d7ff8cf69cb3af473f417e132d8a7d to your computer and use it in GitHub Desktop.
Partition Sets into mutually exclusive subsets
@dynamicMemberLookup
struct Partition<Element: CaseIterable & Hashable, Case: CaseIterable & Hashable> {
private let subsets: [Case: Set<Element>]
private let classify: (Element) -> Case
init(by classify: @escaping (Element) -> Case) {
self.classify = classify
var subsets: [Case: Set<Element>] = Dictionary(
uniqueKeysWithValues: Case.allCases.map { ($0, []) }
)
for element in Element.allCases {
subsets[classify(element)]!.insert(element)
}
self.subsets = subsets
}
subscript(_ case: Case) -> Set<Element> {
subsets[`case`, default: []]
}
func classification(for element: Element) -> Case {
classify(element)
}
}
extension Partition where Case: RawRepresentable, Case.RawValue == String {
subscript(dynamicMember member: String) -> Set<Element> {
guard let key = Case(rawValue: member) else {
return []
}
return subsets[key, default: []]
}
}
@DanielCardonaRojas
Copy link
Author

Example:

struct Rating<Partitioning: Hashable & CaseIterable> {
    let partition: Partition<Fruit, Partitioning>
    let rating: [Partitioning: Double]
    
    func rate(for fruit: Fruit) -> Double {
        let color = partition.classification(for: fruit)
        return rating[color] ?? 0
    }
}

extension Rating where Partitioning == Color {
    static func byColor(ratings: [Color: Double]) -> Rating {
        let partition = Partition<Fruit, Color> { fruit in
            switch fruit {
            case .apple:        return .red
            case .strawberry:   return .red
            case .banana:       return .yellow
            case .mango:        return .yellow
            case .lime:         return .green
            case .blueberry:    return .blue
            }
        }
        return .init(partition: partition, rating: ratings)
    }
    
}
enum Fruit: CaseIterable, Hashable {
    case apple, banana, mango, blueberry, strawberry, lime
}

enum Color: String, CaseIterable, Hashable {
    case red, yellow, green, blue
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment