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

Swift中按指定字段对结构体数组去重的最佳实现方案

结构体数组按name字段高效去重方案

原实现的性能问题

你当前的写法可以得到预期的去重结果,但存在明显的性能缺陷:每次向临时数组追加元素前,都会调用filter遍历整个临时数组统计同名元素数量,整体时间复杂度为O(n²),当数组元素量级较大时性能损耗会非常明显。

原实现代码:

struct DistinctListOnName{
    init(){
        let alist: [myList] = [myList(id: 1, name: "Jeff", status: "A"),
                             myList(id: 2, name: "Mike", status: "A"),
                             myList(id: 3, name: "Mike", status: "B"),
                             myList(id: 4, name: "Ron", status: "B")]
        
        var tmp: [myList] = []
        for i in alist{
            if (tmp.filter({ item in
                item.name == i.name
            }).count == 0) {
                tmp.append(i)
            }
        }
        print(tmp)
    }
}

struct myList {
    var id: Int
    var name: String
    var status: String
    init(id: Int, name: String, status: String){
        self.id = id
        self.name = name
        self.status = status
    }
}

运行后得到预期输出:

[(id: 1, name: "Jeff", status: "A"), (id: 2, name: "Mike", status: "A"), (id: 4, name: "Ron", status: "B")]

O(n)复杂度的优化实现

核心优化思路是额外维护一个Set集合记录已经出现过的name值,利用Set元素查找O(1)的时间特性,把整体时间复杂度降到O(n),不需要每次遍历临时数组做检查:

struct DistinctListOnName{
    init(){
        let alist: [myList] = [myList(id: 1, name: "Jeff", status: "A"),
                             myList(id: 2, name: "Mike", status: "A"),
                             myList(id: 3, name: "Mike", status: "B"),
                             myList(id: 4, name: "Ron", status: "B")]
        
        var tmp: [myList] = []
        // 记录已经出现过的name
        var seenNames = Set<String>()
        for item in alist {
            // Set的insert方法会返回插入是否成功的标记,成功代表name是第一次出现
            if seenNames.insert(item.name).inserted {
                tmp.append(item)
            }
        }
        print(tmp)
    }
}

struct myList {
    var id: Int
    var name: String
    var status: String
    init(id: Int, name: String, status: String){
        self.id = id
        self.name = name
        self.status = status
    }
}

方案优势

  • 去重逻辑和原实现完全一致:保留原数组元素顺序,同名元素默认保留第一次出现的条目
  • 时间复杂度从O(n²)降至O(n),数组元素量级越大,性能提升越明显
  • 去掉了嵌套的filter遍历,代码逻辑更简洁易读

如果有多处类似的按字段去重需求,也可以把这段逻辑封装成Sequence的扩展方法,直接传入去重依据的KeyPath即可复用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:06:20