Search code examples
swiftgenericsnscountedset

NSCountedSet generic function


To see how many Person objects with a specific identifier occur in an NSCountedSet, I created the following function:

public extension NSCountedSet {
    public func countFor(identifier: String) -> Int {
       let p = self.compactMap { $0 as? Person }.filter { $0. identifier == identifier }

       return self.count(for: p)
    }
}

Works great, but it is very specific for Person.

So I am trying to make it generic:

public func countFor<T: Identifiable >(type: T, identifier: String) -> Int {
    let p = self.compactMap { $0 as? T.Type }.filter { $0. identifier == identifier }

    return self.count(for: p)
}

Person conforms to a Identifiable protocol:

public protocol Identifiable {
    var identifier: String { get }
}

and:

extension Person: Identifiable {
    public var identifier: String {
        return name
    }
}

This gives me this error:

Instance member 'identifier' cannot be used on type 'T'

And when I call this function, I get the following error:

Argument type 'Person.Type' does not conform to expected type 'Identifiable'

What am I missing, is there a way to get this to work?


Solution

  • I don't think you even need Generics for that. You can simply do it like,

    public func countFor(identifier: String) -> Int {
        let p = self.compactMap { $0 as? Identifiable }.filter { $0.identifier == identifier }
        return self.count(for: p)
    }
    

    In case, the set contains different types of Identifiable elements having same identifiers, you can resolve it using,

    public func countFor<T: Identifiable>(type: T, identifier: String) -> Int {
        let p = self.compactMap { $0 as? T }.filter { $0.identifier == identifier }
        return self.count(for: p)
    }