Swift数组中特定字符串搜索替换逻辑的代码简化求助
嘿,我来帮你简化这段Swift代码!你的需求核心是把所有带Virtual前缀的运动项替换成去掉前缀的版本,同时确保如果原项(比如Ride)和对应的Virtual版本(VirtualRide)共存时,只保留原项(或者说最终只保留一个基础版本)。
原代码的问题在于只处理了VirtualRide这一种情况,没覆盖VirtualRun,而且用filter.count来判断的方式效率不高(每次filter都会遍历整个数组),逻辑也比较绕。下面给你两种更简洁、扩展性更强的实现方式:
方式一:保持原数组中基础项的出现顺序(优先保留非Virtual项)
这个方法会先把所有非Virtual的基础项按原顺序加入结果,再处理Virtual项(只添加那些还没被加入的基础项),完美匹配你的需求场景:
func processSports(_ sports: [String]) -> [String] { var result = [String]() var seenBaseSports = Set<String>() // 第一步:先收集所有非Virtual的基础项,保证只添加一次 for sport in sports { guard !sport.hasPrefix("Virtual") else { continue } if !seenBaseSports.contains(sport) { result.append(sport) seenBaseSports.insert(sport) } } // 第二步:处理Virtual前缀的项,仅当对应的基础项未被添加时才加入 for sport in sports { guard sport.hasPrefix("Virtual") else { continue } let baseSport = String(sport.dropFirst(7)) // "Virtual"共7个字符 if !seenBaseSports.contains(baseSport) { result.append(baseSport) seenBaseSports.insert(baseSport) } } return result }
方式二:更简洁的函数式写法(适合对顺序要求不严格的场景)
如果不需要严格保持原数组中基础项的出现顺序,或者只要最终结果正确即可,这个写法更紧凑:
func processSports(_ sports: [String]) -> [String] { // 先把所有项转换为对应的基础版本(去掉Virtual前缀) let baseVersions = sports.map { $0.hasPrefix("Virtual") ? String($0.dropFirst(7)) : $0 } // 去重并转换回数组(Set会自动去重,顺序由Set内部决定) return Array(Set(baseVersions)) } // 如果你需要保持转换后数组的顺序(即保留第一个出现的基础项),可以用reduce优化: func processSportsOrdered(_ sports: [String]) -> [String] { return sports.map { $0.hasPrefix("Virtual") ? String($0.dropFirst(7)) : $0 }.reduce(into: (result: [String], seen: Set<String>())) { acc, sport in if !acc.seen.contains(sport) { acc.result.append(sport) acc.seen.insert(sport) } }.result }
测试验证
用你的示例输入测试:
- 输入
["Ride", "VirtualRide", "Run", "VirtualRun"]→ 输出["Ride", "Run"] - 输入
["VirtualRide", "VirtualRun"]→ 输出["Ride", "Run"] - 输入
["Ride", "Run"]→ 输出["Ride", "Run"]
所有情况都符合你的需求,而且代码比原来简洁很多,还能自动处理所有带Virtual前缀的运动项,扩展性拉满!
内容的提问来源于stack exchange,提问作者app4g
相关产品推荐
相关产品推荐

