2

I want to write a partial compare function, defined for all Equatable structs, that would be able to compare two struct instances, but ignoring any properties specified using an argument. Example, where the unicorn operator (🦄 ) represents what I am missing:

struct Struct1: Equatable {
    x: Int
    y: Int
    z: Int
}

func compare<T: Equatable>(_ a: T, _ b: T, ignoring ignoredProperties: [Property]) {   // N.B. “Property” is a made-up type.
    var alteredA = a
    for property in ignoredProperties {
        alteredA🦄 property = b🦄 property
    }
    return alteredA == b
}

let s1 = Struct1(x:1, y:2, z:3)
let s2 = Struct1(x:1, y:2, z:4)  // s2 is the same as s1, except for the value of property “z”

compare(s1, s2, ignoring: [])                  // -> false
compare(s1, s2, ignoring: [Property(Struct1.z)])       // -> true

What can I use instead of 🦄  and Property ?

N.B. I don’t need the ignored properties to be specified at runtime – in this example, they could actually be known at compile time.

N.B. 2. If I need to change my struct into a class, so be it, but I don’t really known how to do what I need using a class either.

0

1 Answer 1

3

You can pass property keypaths to a function and use them like this:

class Person: NSObject {
    dynamic var firstName: String = ""
    dynamic var lastName: String = ""

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}

func setProperty<T: NSObject>(object: T, path: String, value: Any) {
    object.setValue(value, forKey: path)
}

let firstNamePath = #keyPath(Person.firstName)
let chris = Person(firstName: "chris", lastName: "jones")
setProperty(object: chris, path: firstNamePath, value: "notChrisAnyMore")
print(chris.firstName)
Sign up to request clarification or add additional context in comments.

2 Comments

Good. Will be the accepted answer if nobody proposes a way of sticking with structs.
I don't think it can be done with a struct, could be wrong :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.