0

I'm experimenting with writing Swifts .filter function and have run into some confusion. I'm essentially trying to modify this function:

func anotherFilter<T>(elements: [T], predicate: (T) -> Bool) -> [T] {
    var filteredArray = [T]()
    for element in elements {
        if predicate(element) {
            filteredArray += [element]
        }
    }
    return filteredArray
}

Into an extension:

extension Array {
    func anotherFilter<T>(elements: [T], predicate: (T) -> Bool) -> [T] {
        var filteredArray = [T]()
        for element in elements {
            if predicate(element) {
                filteredArray += [element]
            }
        }
        return filteredArray
    }
}

Of course this version of the extension works but it requires that you pass the object in which doesn't make sense:

self.coords.anotherFilter (coords) { self.someOperation(coords, op: $0) }

What I've Tried

Obviously, what I'd like to achieve is something like this:

extension Array {

    func anotherFilter <T>(predicate: (T) -> Bool) -> [T] {
        var filteredArray = [T]()
        for item in self {
            if predicate(item) {
                filteredArray.append(item)
            }
        }
    }
}

But this returns an error:

Cannot invoke 'predicate' with an argument list of type '(Element)'

Question

How do I pass the object (in this case coords) into my extension without parameterizing it? Deeper explanations are most welcome.

Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135

2 Answers2

1

Array already has a placeholder type for its elements: Element. Your generic parameter T is exactly that placeholder type, so you can just use Element:

extension Array {
    func anotherFilter(predicate: (Element) -> Bool) -> [Element] {
        var filteredArray = [Element]()
        for item in self where predicate(item) {
            filteredArray.append(item)
        }
        return filteredArray
    }
}
Siyual
  • 16,415
  • 8
  • 44
  • 58
Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
0

It requires a "self" if the object is not instantiated. I guess it would need to be a static method instead.

static func anotherFilter<T>(elements: [T], predicate: (T) -> Bool) -> [T]
Armin
  • 629
  • 6
  • 23