1

When I filter an Array of Functions to exclude a specific function from the array, the filtered array contains no elements. Any idea of why this is happening?

var array: [()->()] = []

array.append(function1)
array.append(function2)

let function: ()
function = function1()
var filteredArray: [()->()] = []
filteredArray = array.filter { $0() != function }

print(filteredArray.count) // 0
3
  • 1
    Void (empty tuple) it is not a function. Btw ()->() it is not Equatable Commented Sep 11, 2020 at 2:09
  • is that not how to create an array that holds functions? and would just () be equatable? Commented Sep 11, 2020 at 2:34
  • 1
    () is the result of a function that does not return any value. An empty tuple also know as Void. The array declaration is correct. function = function1() will assign the result of function1 to function which is Void. All your functions in your array returns Void (doesn't return anything same as an empty tuple). $0() will execute the function code and return Void therefore all elements are equal to function which is Void thats why it return an empty array. Commented Sep 11, 2020 at 2:46

1 Answer 1

2

Non-Nominal Types cannot be filtered. This is because they are not equatable:

i.e. Here are some Non-Nominal Types

What you could do is create a struct like so:

struct Method: Hashable, Equatable {
    var name: String
    var method: () -> () // or whatever type you want
    init(_ n: String,_ m: @escaping () -> ()) {
        name = n
        method = m
    }

    // Equatable
    static func == (lhs: Method, rhs: Method) -> Bool {
        return lhs.name == rhs.name
    }

    // Hashable
    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
    }
}

So that the name is what checks if methods are equal. But so much for structs.

If you wanted, you could make a similar class instead to keep track of the reference.


Example code:

func function1() {print("foo")}
func function2() {print("bar")}

var array: [Method] = []

array.append(Method("One", function1))
array.append(Method("Two", function2))

let function: Method
function = Method("One", function1)
var filteredArray: [Method] = []
filteredArray = array.filter { $0 != function}

print(filteredArray.count) // 1

filteredArray.first?.method() // prints "bar"
Sign up to request clarification or add additional context in comments.

4 Comments

if your Method struct is equatable { $0.name != function.name } is redundant { $0 != function }
when I try to append the method to the array I get an error "extra argument in call" and a warning "Initialization of 'Method' (aka 'OpaquePointer') results in a dangling pointer"
@stepjesse I just fixed a bug in the code, so that should do the trick. Please respond if it still doesn't work.
took me some time to implement it into my game correctly but it works perfectly thank you!

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.