2

I'm trying to create an extension but somehow it keeps saying:

Ambiguous reference to member '=='.

class Foo: Equatable {
    var string = ""
    var number = 0

    init(string: String, number: Int) {
        self.string = string
        self.number = number
    }
}

extension Array where Iterator.Element: Foo {

    mutating func replace(object: Foo) {
        if let index = index(where: { $0.number == object.number}) {
            self[index] = object
        }
    }
}

func ==(lhs: Foo, rhs: Foo) -> Bool {
    return lhs.number == rhs.number
}

What am I doing wrong?

2
  • Foo doesn't conform to Equatable. It needs a definition for == Commented Nov 6, 2016 at 6:20
  • Sorry, I do have it, but I just havent shown in the example. Commented Nov 6, 2016 at 6:30

2 Answers 2

4

Try this:

extension Array where Element: Foo {

    mutating func replace(object: Element) {
        if let index = index(where: {$0.number == object.number}) {
            self[index] = object
        }
    }

}

To make self[index] = object valid, object needs to be an Element of the Array, which can be any subclass of Foo.

And unfortunately, Swift cannot infer the type of Element from the constraint to Iterator.Element. You may need to declare the constraint to Element directly.

(And to test the code above, I have removed : Equatable from your Foo, which is irrelevant when you use index(where:) in the extension.)

Sign up to request clarification or add additional context in comments.

1 Comment

There are many combinations -- extension constraint, object type, using index(where:) or index(of:)... My answer is just an example and there may be another combination which fits for your purpose. Please find one by your self.
1

Swift 5 version and support multiple object replacement(add if not exist).

extension Foo {
    public static func == (lhs: Object, rhs: Object) -> Bool {
        return lhs.id == rhs.id
    }
}

extension Array where Element: Foo {
    mutating func replace(object: Element) -> Bool {
        if let index = firstIndex(where: {$0 == object}) {
            self[index] = object
            return true
        }
        return false
    }

    mutating func replace(objects: Array<Element>) {
        objects.forEach { (object) in
            if replace(object: object) == false {
                self.append(object)
            }
        }
    }
}

Comments

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.