You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift实现支持传入函数为参数的Array扩展mapThenUnique及报错解决

报错原因解析

初始版本3个报错原因

  • 报错1:filter 方法的返回值是原数组类型 [Element],你直接把它转换成 Array<T> 赋值给 mapped 变量,类型不匹配。
  • 报错2:你给 f 传入的参数是整个数组 self,但 f 要求的入参是单个 Element 类型,类型不匹配。
  • 报错3:filter 要求传入的参数是一个 (Element) throws -> Bool 类型的闭包,你传入的是 f(self) 执行后返回的 T 类型值,完全不符合参数要求。

(Element) throws -> Bool 含义说明

这是Swift中的函数类型定义:

  • 左侧的 Element 代表函数接收一个 Element 类型的入参
  • 中间的 throws 代表函数执行过程中允许抛出错误
  • 右侧的 Bool 代表函数返回值为布尔类型
    你给需要传入函数的参数位传了普通值,自然会触发类型不匹配报错。

修改后版本的问题解析

1. for循环变量名错误

你定义的映射后数组变量是 mapped,但for循环写的是 for element in filtered,filtered 变量不存在,会触发未定义标识符报错。

2. contains方法使用错误

contains(where:) 的参数要求是 (T) throws -> Bool 类型的判断闭包,你直接传入 T 类型的 element 变量,类型不匹配。
如果你要判断数组中是否已经存在当前元素,有两种正确写法:

  • 直接使用不需要闭包的 contains 方法:noDups.contains(element)(因为你声明了T遵守Comparable协议,而Comparable默认继承Equatable,满足contains普通版本的约束)
  • 坚持用contains(where:)的话要写闭包:noDups.contains(where: { $0 == element })

3. 排序后结果的问题

你调用了noDups.sort()会对去重后的结果按升序排列,所以字符串示例返回["abc", "hi"]是正常排序结果,和你给出的功能示例要求一致。


可正常运行的最终代码

extension Array {
    func mapThenUnique<T: Comparable>(f: (Element) -> T) -> Array<T> {
        let mapped = self.map{ f($0) }
        var noDups: Array<T> = []
        for element in mapped {
            if !noDups.contains(element) { 
                noDups.append(element) 
            }
        }
        noDups.sort()
        return noDups
    }
}

// 测试用例验证
print(["abc", "Hi", "AbC"].mapThenUnique { $0.lowercased() }) // 输出 ["abc", "hi"]
print([2, 9, -9, 3].mapThenUnique { Int($0) * $0 }) // 输出 [4, 9, 81]

内容的提问来源于stack exchange,提问作者ThreeRingBinder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 18:06:03