4

I have an array called remindersArray that contains a custom object called Reminder (each Reminder object has title and identifier).

Inside Reminder I have a static fun called removeReminderWithIdentifier that should find the reminder and delete it from the array.

I've tried to do it like this:

static func removeReminderWithIdentifier(reminderIdentifier: String) {
    for currentReminder in Reminder.remindersArray {
        if currentReminder.identifier == reminderIdentifier {
            Reminder.remindersArray.removeAtIndex(Reminder.remindersArray.indexOf(currentReminder)) //Compile error
        }
    }
}

but it gives me this compile error:

Cannot convert value of type 'Reminder' to expected argument type '@noescape (Reminder) throws -> Bool'

Any idea how can I remove that object with this identifier from the array?

Thanks!

1
  • I ran into the exact same problem! Commented Oct 9, 2017 at 22:01

2 Answers 2

2

See the header of two indexOf(_:) methods for CollectionType:

extension CollectionType where Generator.Element : Equatable {
    /// Returns the first index where `value` appears in `self` or `nil` if
    /// `value` is not found.
    ///
    /// - Complexity: O(`self.count`).
    @warn_unused_result
    public func indexOf(element: Self.Generator.Element) -> Self.Index?
}

extension CollectionType {
    /// Returns the first index where `predicate` returns `true` for the
    /// corresponding value, or `nil` if such value is not found.
    ///
    /// - Complexity: O(`self.count`).
    @warn_unused_result
    public func indexOf(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Index?
}

If you want to use the first indexOf(_:) (which you are trying in your code), the element type needs to be Equatable. When your Reminder class does not conform to Equatable, Swift ignores the first indexOf(_:), so the second can be the only candidate, having @noescape (Self.Generator.Element) throws -> Bool as its only argument. In your case Self.Generator.Element is Reminder.

So, one way to avoid this error is making your Reminder conform to Equatable.

extension Reminder: Equatable {}
func == (lhs: Reminder, rhs: Reminder) -> Bool {
    return lhs.identifier == rhs.identifier /* && ... you may need more complex condition. */
    /* return lhs === rhs //or simple use `===`. */
}

But you have some options to do it:

If your reminderArray contains just one element for each unique identifier, you can write something like this, without making your Reminder Equatable:

static func removeReminderWithIdentifier(reminderIdentifier: String) {
    if let index = Reminder.remindersArray.indexOf({$0.identifier == reminderIdentifier}) {
        Reminder.remindersArray.removeAtIndex(index)
    }
}

If your remindersArray may contain multiple Reminder instances having the same identifier, this should work:

static func removeReminderWithIdentifier3(reminderIdentifier: String) {
    Reminder.remindersArray = Reminder.remindersArray.filter{$0.identifier != reminderIdentifier}
}

Choose one (or more?) and make it a try.

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

Comments

1

You could filter out the unwanted reminders:

static func removeReminderWithIdentifier(reminderIdentifier: String) {
    Reminder.remindersArray = Reminder.remindersArray.filter { $0.identifier != reminderIdentifier }
}

Alternately:

func removeReminderWithIdentifier(reminderIdentifier: String) {
    remindersArray = remindersArray.filter { $0.identifier != reminderIdentifier }
}

And in the latest swift naming style...:

func removeReminders(with identifier: String) {
    remindersArray = remindersArray.filter { $0.identifier != identifier }
}

2 Comments

Cannot call value of non-function type '[Reminder]'
Without seeing your code I am guessing... Remove the static prefix and also the two references to Reminder in the func. I've updated the answer accordingly.

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.