Find index of object in an array of type [SomeProtocol]

放肆的年华 提交于 2019-11-27 04:07:56

问题


I have an array called subscribers that stores objects which conform to the protocol JABPanelChangeSubscriber. The protocol is declared as

public protocol JABPanelChangeSubscriber {

}

and my array is declared as:

var subscribers = [JABPanelChangeSubscriber]()

Now I need to implement a method to add a subscriber to the list, but it first has to check that that subscriber has not already been added before.

public func addSubscriber(subscriber: JABPanelChangeSubscriber) {
    if subscribers.find(subscriber) == nil { // This ensures that the subscriber has never been added before
        subscribers.append(subscriber)
    }
}

Unfortunately, JABPanelChangeSubscriber is not Equatable, and I can't figure out how to make it Equatable, so the find method is giving me an error. Can anyone help me out with a fix or with a suggestion for a different approach?

Thanks


回答1:


Assuming that all types implementing your protocol are reference types (classes), you can declare the protocol as a "class protocol"

public protocol JABPanelChangeSubscriber : class {

}

and use the identity operator === to check if the array already contains an element pointing to the same instance as the given argument:

public func addSubscriber(subscriber: JABPanelChangeSubscriber) {
    if !contains(subscribers, { $0 === subscriber } ) {
        subscribers.append(subscriber)
    }
}



回答2:


Add isEqualTo(:) requirement to JABPanelChangeSubscriber protocol

public protocol JABPanelChangeSubscriber {
    func isEqualTo(other: JABPanelChangeSubscriber) -> Bool
}

Extension to JABPanelChangeSubscriber protocol with Self requirement

extension JABPanelChangeSubscriber where Self: Equatable {
   func isEqualTo(other: JABPanelChangeSubscriber) -> Bool {
      guard let other = other as? Self else { return false }
        return self == other
   }
}

Remember to make objects conform Equatable protocol too

class SomeClass: Equatable {}
func == (lhs: SomeClass, rhs: SomeClass) -> Bool {
//your code here
//you could use `===` operand
}

struct SomeStruct: Equatable {}
func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
//your code here
}

Then find the index

func indexOf(object: JABPanelChangeSubscriber) -> Int? {
    return subcribers.indexOf({ $0.isEqualTo(object) })
}

If you want to check the existence of an object before adding them to the array

func addSubscriber(subscriber: JABPanelChangeSubscriber) {
    if !subscribers.contains({ $0.isEqualTo(subscriber) }) {
        subscribers.append(subscriber)
    }
}


来源:https://stackoverflow.com/questions/30344222/find-index-of-object-in-an-array-of-type-someprotocol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!