斯威夫特没有打电话给我的" =="扩展CollectionType

时间:2016-02-09 19:03:34

标签: swift equatable

我有一个继承自NSManagedObject的自定义类(VotingOption),有时我想检查数组中的某些投票选项是否重复。我试图让我的代码尽可能通用。这就是我为扩展CollectionType协议所做的工作:

extension CollectionType where Self.Generator.Element : Equatable {

    var duplicates: [Self.Generator.Element]{
        return = self.filter { element in
            return self.filter { $0 == element }.count != 1
        }
    }

    var hasDuplicates: Bool {
        return (self.duplicates.count != 0)
    }
}

这就像魅力一样,除了它没有使用全局函数:

func ==(lhs: VotingOption, rhs: VotingOption) -> Bool {
     return (lhs.location?.title.lowercaseString == rhs.location?.title.lowercaseString) && (lhs.startDate == rhs.startDate)
}

当我做这样的事情时:

let temp: [VotingOption] = votingOptions?.array as? [VotingOption]
if temp.hasDuplicates {
     //do something
}

当我在VotingOption中扩展isEqual时:

class VotingOption: NSManagedObject {

    override func isEqual(object: AnyObject?) -> Bool {

        if let rhs = object as? VotingOption {
            return (self.location?.title.lowercaseString == rhs.location?.title.lowercaseString) && (self.startDate == rhs.startDate)
        } else {
            return false
        }
    }
    ...
    ...
    ... rest of class
}

应用程序崩溃,它指向AppDelegate,其中包含" libc ++ abi.dylib:以NSException类型的未捕获异常终止"错误

如何告诉" =="在CollectionType中使用VotingOption的全局函数?

2 个答案:

答案 0 :(得分:1)

这是一个实现duplicateshasDuplicates两次的解决方案,一次用于Equatable元素,一次用于VotingOptions类。为了尽可能减少代码重复,我已经定义了一个通用实现来查找重复项,允许你传递一个比较两个元素的函数/闭包:

extension CollectionType {

    func findDuplicates(checkEqual: (Self.Generator.Element, Self.Generator.Element) -> Bool) -> [Self.Generator.Element]{
        return self.filter { element in
            return self.filter { checkEqual($0, element) }.count != 1
        }
    }
}

extension CollectionType where Self.Generator.Element : Equatable {

    var duplicates: [Self.Generator.Element]{
        return self.findDuplicates(==)
    }

    var hasDuplicates: Bool {
        return (self.duplicates.count != 0)
    }
}

extension CollectionType where Self.Generator.Element : VotingOption {

    var duplicates: [Self.Generator.Element]{
        return self.findDuplicates {lhs, rhs in
            return (lhs.location?.title.lowercaseString == rhs.location?.title.lowercaseString) && (lhs.startDate == rhs.startDate)
        }
    }

    var hasDuplicates: Bool {
        return (self.duplicates.count != 0)
    }
}

答案 1 :(得分:0)

感谢所有帮助过的人。我将在这里发布最终实施: 基本上创建了一个新协议" Identity"用方法"等于"这基本上是" =="最后为NSManagedObjects添加了一个通用扩展,实现了#34; Identity"这基本上是" =="在"等于"方法。但是在" VotingOption"为了满足我的特殊需求,我已经覆盖了这个功能。最后,集合类型被扩展到了"元素"是"身份"。而不是" =="它称为"等于"方法:)

protocol Identity {
     func equals(rhs: Self) -> Bool
}

extension Identity where Self: NSManagedObject {
     func equals(rhs: Self) -> Bool {
          return self == rhs
     }
}

extension CollectionType where Self.Generator.Element : Identity {

    var duplicates: [Self.Generator.Element] {

        return self.filter { element in
            return self.filter { $0.equals(element) }.count != 1
        }
    }

    var hasDuplicates: Bool {
        return (self.duplicates.count > 0)
    }
}

class VotingOption: NSManagedObject, Identity {

    func equals(rhs: VotingOption) -> Bool {

    //... implementation here
    }
}