Swift实现:对比另一个数组排序,将共同元素前置
问题描述
我有两个数组:
@State var myInterests: [String] = ["Beer", "Food", "Dogs", "Ducks"] @State var otherInterests: [String] = ["Ducks", "Baseball", "Beer", "Pasta"]
我需要展示一个列表,将所有共同兴趣放在列表顶部,其余兴趣放在后面。当前使用的列表代码是:
ForEach(interests, id: \.self) { tag in Text(tag) }
otherInterests排序后的预期结果应为:
["Ducks", "Beer", "Baseball", "Pasta"]
请问是否有办法对数组进行排序,将共同兴趣移到数组前面,其余元素放在后面?
解决方案
当然可以,通过数组的sorted(by:)方法自定义排序规则就能实现,以下是几种实用方案:
方案1:保留非共同元素原有顺序
如果希望非共同元素维持在原数组中的顺序,用这个逻辑:
let sortedInterests = otherInterests.sorted { first, second in let firstIsCommon = myInterests.contains(first) let secondIsCommon = myInterests.contains(second) // 核心规则:共同兴趣优先排在前面;同类型元素保持原数组顺序 if firstIsCommon != secondIsCommon { return firstIsCommon } else { guard let firstIdx = otherInterests.firstIndex(of: first), let secondIdx = otherInterests.firstIndex(of: second) else { return false } return firstIdx < secondIdx } }
方案2:非共同元素按字母排序
如果希望非共同元素按字母顺序排列,简化排序逻辑即可:
let sortedInterests = otherInterests.sorted { first, second in let firstIsCommon = myInterests.contains(first) let secondIsCommon = myInterests.contains(second) if firstIsCommon != secondIsCommon { return firstIsCommon } else { // 共同元素也可以按字母排序,按需调整 return first < second } }
在SwiftUI中使用
直接将排序后的数组传入ForEach:
ForEach(sortedInterests, id: \.self) { tag in Text(tag) }
性能优化建议
如果数组元素较多,contains方法每次查询是O(n)复杂度,建议把myInterests转成Set,将查询效率提升到O(1):
let myInterestsSet = Set(myInterests) let sortedInterests = otherInterests.sorted { first, second in let firstIsCommon = myInterestsSet.contains(first) let secondIsCommon = myInterestsSet.contains(second) if firstIsCommon != secondIsCommon { return firstIsCommon } else { guard let firstIdx = otherInterests.firstIndex(of: first), let secondIdx = otherInterests.firstIndex(of: second) else { return false } return firstIdx < secondIdx } }
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

