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

Swift获取数组唯一元素时如何保持原顺序并保证ID与名称对应

解决Swift中去重后数组元素对应关系混乱的问题

这个问题的核心是你把nationalitiesid和nationalities拆成两个独立数组处理,用Set去重时会打乱原有顺序,而且没法保证两个数组的元素对应关系。咱们换个思路,先把国籍ID和名称绑定成一组数据,再对这组数据去重并保留顺序,最后拆分回两个数组就能解决问题。

具体解决方案

第一步:绑定关联数据,避免拆分数组

先把循环里的逻辑改成收集配对的(id, name)元组,而不是分别存入两个数组,这样能始终保证ID和名称的对应关系:

// 先读取一次nationalities数组,避免循环里重复IO操作(优化点)
guard let decoded4 = userDefaults.object(forKey: "nationalities") as? Data,
      let decodedNationalities = NSKeyedUnarchiver.unarchiveObject(with: decoded4) as? [Nationality] else {
    // 处理解码失败的情况,别用强制解包!
    return
}

// 定义数组保存配对的ID和名称
var nationalityPairs = [(id: Int, name: String)]()

for shift in filtered_shifts {
    // 用first(where:)替代内层循环,效率更高
    if let matchedNationality = decodedNationalities.first(where: { $0.id == shift.idNationality }) {
        nationalityPairs.append((id: matchedNationality.id, name: matchedNationality.name))
    }
}

第二步:去重并保留顺序

这里有两种靠谱的方式,都能保证去重后ID和名称的对应关系,同时保留首次出现的顺序:

方式一:利用有序字典(Swift 4.2+)

Swift 4.2之后的Dictionary会保留插入顺序,我们用ID作为key自动去重,再提取值即可:

// 用ID作为key,自动去重,保留首次出现的配对
let uniquePairDict = Dictionary(nationalityPairs.map { ($0.id, $0) }, uniquingKeysWith: { first, _ in first })
// 提取有序的配对数组
let sortedUniquePairs = Array(uniquePairDict.values)

// 拆分回目标数组
uniqueNationalityid = sortedUniquePairs.map { $0.id }
uniqueNationality = sortedUniquePairs.map { $0.name }
方式二:手动遍历去重(兼容旧版本Swift)

用一个辅助Set记录已经处理过的ID,遍历配对数组时只保留首次出现的元素:

var seenIds = Set<Int>()
var uniquePairs = [(id: Int, name: String)]()

for pair in nationalityPairs {
    if !seenIds.contains(pair.id) {
        seenIds.insert(pair.id)
        uniquePairs.append(pair)
    }
}

// 拆分回目标数组
uniqueNationalityid = uniquePairs.map { $0.id }
uniqueNationality = uniquePairs.map { $0.name }

为什么原来的方法会出错?

Set是无序集合,转换回数组时的元素顺序是不确定的,所以两个独立数组去重后,uniqueNationalityid和uniqueNationality的元素对应关系就会混乱。而把ID和名称绑定成一组数据处理,就能始终保证每一组的对应关系,去重后顺序也完全符合预期。

内容的提问来源于stack exchange,提问作者mrs.bassim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:07