从数组中删除自定义对象 (Swift)

Posted

技术标签:

【中文标题】从数组中删除自定义对象 (Swift)【英文标题】:Remove a custom object from an array (Swift) 【发布时间】:2016-09-03 10:10:29 【问题描述】:

我有一个名为remindersArray 的数组,其中包含一个名为Reminder 的自定义对象(每个Reminder 对象都有titleidentifier)。

Reminder 内部,我有一个名为removeReminderWithIdentifier 的静态乐趣,它应该找到提醒并将其从数组中删除。

我试过这样做:

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

但它给了我这个编译错误:

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

知道如何从数组中删除带有此标识符的对象吗?

谢谢!

【问题讨论】:

我遇到了完全相同的问题! 【参考方案1】:

查看CollectionType的两个indexOf(_:)方法的标题:

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?

如果您想使用第一个 indexOf(_:)(您正在代码中尝试),则元素类型需要为 Equatable。当您的 Reminder 类不符合 Equatable 时,Swift 会忽略第一个 indexOf(_:),因此第二个可能是唯一的候选者,将 @noescape (Self.Generator.Element) throws -> Bool 作为其唯一参数。在您的情况下,Self.Generator.ElementReminder

因此,避免此错误的一种方法是使您的 Reminder 符合 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 `===`. */

但你有一些选择:

如果你的reminderArray 只包含一个元素对应每个唯一的identifier,你可以写这样的东西,而不用让你的Reminder Equatable

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

如果您的remindersArray 可能包含多个具有相同identifierReminder 实例,则应该可以:

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

选择一个(或更多?)并尝试一下。

【讨论】:

【参考方案2】:

您可以过滤掉不需要的提醒:

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

交替:

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

并且采用最新的 swift 命名风格...:

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

【讨论】:

Cannot call value of non-function type '[Reminder]' 没有看到你的代码我猜...删除 static 前缀以及函数中对 Reminder 的两个引用。我已经相应地更新了答案。

以上是关于从数组中删除自定义对象 (Swift)的主要内容,如果未能解决你的问题,请参考以下文章

Swift中自定义对象和自定义对象数组的通用属性[重复]

iOS,Swift:如何保存包含自定义对象的数组以便我可以加载以供重用?

在 Swift 中使用自定义对象填充数组

存储自定义对象数组 Swift

Swift:确定自定义对象数组是不是包含特定字符串[重复]

Swift 4 如何将自定义对象数组转换为 JSON