基于指定Key去除NSObject数组重复项:扩展方法报错排查
解决Core Data数组去重扩展方法的报错问题
嘿,我看你在给Core Data返回的数组写去重扩展时遇到了类型不匹配的报错,咱们来一步步捋清楚问题出在哪~
首先还原你的问题场景:调用扩展方法时出现了这个报错:
cannot convert the value type of ()-> to expected argument type [Object type]->()
你的调用代码和未完成的扩展是这样的:
override func viewDidLoad() { // 此处出现上述报错 let uniqueArray = myArray.unique{$0.Id} } extension Array { func unique<T:Hashable>(map: ((Element) -> (T))) -> [Element] { var set = Set<T>() var arrayOrdered = [Element... } }
问题根源分析
- 扩展方法未完成:你写的
unique方法只开了个头,arrayOrdered的定义和后续去重逻辑都没写完,Swift没法正确推断这个方法的完整类型,这是触发报错的核心原因。 - 闭包调用的参数标签问题:你的方法定义里参数带标签
map:,但调用时直接用尾随闭包却没匹配标签规则;如果想用简洁的尾随闭包,需要在方法定义时给参数加上_来允许省略标签。 - 类型推断连锁错误:因为方法本身不完整,Swift无法准确识别闭包的输入输出类型,进而抛出了这个看起来有点模糊的类型转换报错。
修正后的完整代码
先补全扩展方法,同时调整参数标签让调用更简洁:
extension Array { // 用_省略参数标签,支持尾随闭包直接调用 func unique<T: Hashable>(_ map: (Element) -> T) -> [Element] { var seen = Set<T>() return filter { element in let key = map(element) guard !seen.contains(key) else { return false } seen.insert(key) return true } } }
然后在viewDidLoad里的正确调用方式(两种都可用):
override func viewDidLoad() { super.viewDidLoad() // 方式1:尾随闭包(推荐,更简洁) let uniqueArray = myArray.unique { $0.Id } // 方式2:带参数标签调用 // let uniqueArray = myArray.unique(map: { $0.Id }) }
额外注意点
要确保你的Core Data实体里的Id属性是符合Hashable协议的类型,比如String、Int、UUID这些,毕竟我们要用它来做Set的重复判断依据。
内容的提问来源于stack exchange,提问作者danu
相关产品推荐
相关产品推荐

