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

Swift 4.0.2中多维数组去重及数组Equatable合规性问题

解答你的Swift数组相关问题

咱们结合你使用的Swift 4.0.2版本,逐个拆解你遇到的三个问题:

1. 数组是否符合Equatable协议?能否使用==进行比较?

在Swift 4.0.2里,数组本身并没有直接遵守Equatable协议,但有个特殊情况:苹果给部分特定类型的数组(比如[String])单独实现了==运算符,所以这类数组可以直接用==比较。

而泛型场景下的条件一致性(也就是当数组元素Element遵守Equatable时,数组[Element]自动获得Equatable支持),是Swift 4.1才正式引入的特性。所以在你的4.0.2版本里,不是所有数组都能使用==,只有少数系统提前适配的数组类型可以,其他类型(比如[Int])不行,除非你自己实现比较逻辑。

2. 为何字符串数组与Int数组的比较表现存在差异?

这完全是Swift 4.0.2的版本局限性导致的:

  • 对于[String],标准库单独实现了==运算符,所以你能直接比较两个字符串数组是否相等。
  • 对于[Int]这类基础类型数组,4.0.2既没有泛型条件一致性支持,也没有单独为[Int]实现==,同时编译器可能因为存在其他全局==实现而产生歧义,所以会抛出“Ambiguous use of operator '=='”的错误。

这个问题在Swift 4.1及以上版本就被彻底修复了,因为新版本引入了完整的条件一致性,只要数组元素遵守Equatable,数组就自动支持==比较。

3. 如何实现多维数组的去重?

你的现有扩展要求Element : Equatable,但在4.0.2里,[Int]并不遵守Equatable(缺少条件一致性),所以[[Int]]调用removeDups()会报错。这里给你两个可行的解决方案:

方案1:手动添加数组的条件Equatable实现(适配4.0.2)

我们可以自己模拟Swift 4.1+的条件一致性行为,给数组添加一个扩展,让元素为Equatable的数组也遵守Equatable:

extension Array : Equatable where Element : Equatable {
    public static func == (lhs: Array, rhs: Array) -> Bool {
        guard lhs.count == rhs.count else { return false }
        for (index, element) in lhs.enumerated() {
            if element != rhs[index] {
                return false
            }
        }
        return true
    }
}

添加这个扩展后,[Int]就会自动遵守Equatable,你的原有removeDups()方法就能直接用于多维数组了:

let multiDimArr : [[Int]] = [[1,2,3], [1,2,3], [1,2 ,4]]
multiDimArr.removeDups() // 返回 [[1,2,3], [1,2,4]],正常工作

方案2:修改去重扩展,支持自定义相等判断(更通用)

如果不想依赖Equatable,可以把去重扩展改成接受一个自定义的相等判断闭包,这样不管元素是否遵守Equatable,都能实现去重:

extension Array {
    func removeDups(by areEqual: (Element, Element) -> Bool) -> [Element] {
        var result = [Element]()
        for element in self {
            if !result.contains(where: { areEqual($0, element) }) {
                result.append(element)
            }
        }
        return result
    }
}

使用时,手动传入多维数组的比较逻辑:

let multiDimArr : [[Int]] = [[1,2,3], [1,2,3], [1,2 ,4]]
// 如果你已经加了方案1的Equatable扩展,可以直接用$0 == $1
let uniqueArr = multiDimArr.removeDups { $0 == $1 }

// 或者直接写完整的比较逻辑,不需要依赖Equatable
let uniqueArr = multiDimArr.removeDups { lhs, rhs in
    guard lhs.count == rhs.count else { return false }
    for (lElement, rElement) in zip(lhs, rhs) {
        if lElement != rElement { return false }
    }
    return true
}

当然,如果你能升级到Swift 4.1+版本,一切会更简单——系统已经原生支持数组的条件一致性,[Int]会自动遵守Equatable,你的原有removeDups()扩展直接就能处理多维数组,不需要任何额外修改。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:02:39