Swift中如何实现两个数组按元素一对一匹配相减取差集
数组一对一匹配相减实现
问题背景
需要实现两个数组的差集计算,但和常规去重差集逻辑不同,要求一对一匹配移除:每在array2中匹配到一个和array1元素相同的值,仅移除array1中一个对应元素,而非移除array1中所有同值元素。
测试用例:
var array1 = ["the", "people", "prefer", "to", "go", "to", "the","sun","beach"] var array2 = ["the", "people", "prefer", "go", "to", "the", "moon","beach"]
- 预期输出:
["to","sun"] - 原有错误实现:
let reuslt = array1.filter { !array2.contains($0) } - 错误原因:
contains判断只会做存在性校验,只要array2里有对应值,array1里所有同值元素都会被过滤,最终仅输出["sun"],不符合需求。
正确实现
核心逻辑:维护array2的可变副本,记录还未被匹配消耗的元素。遍历array1时,若当前元素能在副本中找到匹配,就删除副本中第一个匹配的元素(消耗一次匹配额度,当前元素不保留);若找不到匹配,就将当前元素加入结果集。
func oneByOneSubtract<T: Equatable>(_ origin: [T], subtract target: [T]) -> [T] { var remainToMatch = target return origin.filter { item in guard let matchIndex = remainToMatch.firstIndex(of: item) else { // 无匹配项,保留当前元素 return true } // 匹配到对应元素,消耗一个匹配额度,不保留当前元素 remainToMatch.remove(at: matchIndex) return false } } // 调用示例 let result = oneByOneSubtract(array1, subtract: array2) print(result) // 打印结果:["to", "sun"]
逻辑验证
对照测试用例核对匹配过程:
- array1中"the"出现2次,array2中"the"出现2次,全部匹配消耗,无剩余
- array1中"to"出现2次,array2中"to"出现1次,匹配消耗1次后剩余1个"to"保留
- "sun"在array2中无匹配项,直接保留
- 其余元素两边出现次数一致,全部匹配消耗
最终结果完全符合预期。
内容的提问来源于stack exchange,提问作者SwiftuiCodeHelp
相关产品推荐
相关产品推荐

