Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common Equatable class on Swift

I need container for Any Equatable items in NOT Generic class (for example UI classes initial from storyboard). I need like this

var items: [Equatable]?

but it don't work, Equatable need Generic. the problem that there is no exist common Equatable class.


Ok - Go to generic! But if I do this

class Item<Value: Equatable>: Equatable {
   var value: Value
   init(_ value: Value) {
       self.value = value
   }
   //Equatable
   public static func ==(lhs: Item, rhs: Item) -> Bool {
       return (lhs.value == rhs.value)
   }
}

then I will be forced to specify the type in my nonGeneric-UI class. Like this

var items: [Item<WhatShouldBeHere?>]?

but again we come to the problem that there is no exist common Equatable class


Any solutions for container for All Equatable?

like image 244
EvGeniy Ilyin Avatar asked Dec 03 '25 07:12

EvGeniy Ilyin


1 Answers

In lieu of existential types, you need to use a type eraser:

public struct AnyEquatable: Equatable {
    public let value: Any
    private let equals: (Any) -> Bool

    public init<E: Equatable>(_ value: E) {
        self.value = value
        self.equals = { ($0 as? E) == value }
    }

    public static func == (lhs: AnyEquatable, rhs: AnyEquatable) -> Bool {
        return lhs.equals(rhs.value) || rhs.equals(lhs.value)
    }
}

example usage:

let items = [
    AnyEquatable(1),
    AnyEquatable(1.23),
    AnyEquatable(true),
    AnyEquatable("some string")
]

let desired = "some string"
let desiredAsAnyEquatable = AnyEquatable(desired)
let desiredDescription = String(reflecting: desired)

for item in items {
    let itemDescription = String(reflecting: item.value)
    let isEqualToDesired = item == desiredAsAnyEquatable
    print("\(itemDescription) is \(isEqualToDesired ? "": "not ")equal to \(desiredDescription)")
}

Example output:

1 is not equal to "some string"

1.23 is not equal to "some string"

true is not equal to "some string"

"some string" is equal to "some string"

like image 79
Alexander Avatar answered Dec 05 '25 19:12

Alexander



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!