Jos*_*oid 1 arrays protocols swift
我正在尝试创建一个扩展,Array
根据应用了闭包的项返回一个新的唯一项数组.
例如:如果我有一个Apple
苹果具有属性名称和来源的数组,那么我将调用每个来源的一个Appleapple.uniqued(on: { $0.origin })
这是我到目前为止的代码:
extension Array where Element: Equatable {
func uniqued(on extract: (Element) -> Equatable) { // A
let elementsAndValues = map { (item: $0, extracted: extract($0)) } // 1
var uniqueValues: [Element] = []
var uniqueExtracts: [Equatable] = [] // A
elementsAndValues.forEach { (item, extracted) in
if !uniqueExtracts.contains(extracted) { // 3, B
uniqueValues += [item]
uniqueExtracts += [extracted]
}
}
return uniqueValues
}
}
Run Code Online (Sandbox Code Playgroud)
这应该如下工作:
我得到的错误是:
A)"协议'SomeProtocol'只能用作通用约束,因为它具有Self或相关类型要求"(两次)
B)"缺少参数标签"其中:'在通话中'
我正在使用最新版本的Xcode.任何建议都会有很多帮助.非常感谢.
您有多个问题混合在一起以创建您所看到的错误.你应该做的是使用通用.
extension Array
{
func uniqued<T:Equatable>(on extract:(Array.Element) -> T) -> [Array.Element]
{
let elementsAndValues = self.map{ (item: $0, extracted: extract($0)) }
var uniqueValues:[Element] = []
var uniqueExtracts:[T] = []
for (item, extracted) in elementsAndValues
{
if !uniqueExtracts.contains(extracted)
{
uniqueValues.append(item)
uniqueExtracts.append(extracted)
}
}
return uniqueValues
}
}
Run Code Online (Sandbox Code Playgroud)
该<T:Equatable>
声明了一个泛型类型参数T
符合Equatable
.然后函数签名可以期望一个闭包,它返回一些T
我们知道Equatable
从尖括号中的类型约束符合的泛型类型.您还必须将每次出现更改Equatable
为泛型参数T
,因为Equatable
它不是真实类型; 在这里看到我的答案.如果你这样做,代码应该编译.
您还应该更改一些其他内容:
而不是使用elementsAndValues.forEach(:)
,使用for <pattern> in list {}
循环.
虽然这是有争议的,但在向数组添加一个元素时,您应该使用该Array().append(:)
方法而不是+=
连接.+=
相反+
,在这种情况下,这纯粹是为了传达意图.
您没有为函数声明返回类型,因此编译器假定它返回Void
,因此该return uniqueValues
语句将导致编译器错误.添加一个-> [Array.Element]
功能来解决这个问题.
where Element:Equatable
作为对Array
自身的约束是多余的.您正在使用键函数来确定均衡性,因此元素本身是否相等是无关紧要的.
您可能希望使用一个Set
或一些其他散列数据结构而不是uniqueExtracts
数组.测试数组中的成员资格是一项O(n)
操作.
归档时间: |
|
查看次数: |
99 次 |
最近记录: |