SwiftUI类Tinder应用如何基于食物偏好Set实现用户匹配
结论
- 用
.filter()实现这套食物偏好匹配逻辑完全可行,是当前技术栈下实现成本最低、运行效率最高的方案,完美适配你现有的Set存储结构。
前置修复
先改你现有代码里的编译错误:FoodDataService中第一个数组元素错写为Comida类型,统一替换为Food即可:
class FoodDataService { static let foods: [Food] = [ Food(id: 0, name: "Asado", foodImage: ["asado"]), Food(id: 1, name: "Pizzas", foodImage: ["pizzas"]), Food(id: 2, name: "Milanesas", foodImage: ["milanesas"]), Food(id: 3, name: "Empanadas", foodImage: ["empanadas"]) ] }
注意:你当前
Person的初始化方法里写死了默认食物偏好,接入真实用户数据时记得替换成动态数据源,否则所有待匹配用户的偏好都会固定为Empanadas和Asado。
核心实现逻辑
你的Food模型已经正确实现了基于id的Equatable与Hashable协议,Swift的Set原生支持交集运算,不需要手动写循环遍历比对,直接用Set的intersection方法判断是否存在共同偏好即可:
// 传入CardStack前,先对待匹配用户数组做筛选 // allCandidates是全量待匹配的Person数组,currentUser是当前登录用户实例 let matchedPeople = allCandidates.filter { candidate in // 两个偏好集合的交集非空,即代表存在共同喜欢的食物 !candidate.foodLikings.intersection(currentUser.foodLikings).isEmpty }
筛选完成后直接把结果传入CardStack组件就能正常展示匹配用户:
CardStack(people: matchedPeople)
可选扩展功能
如果后续需要按匹配度排序(共同偏好越多的用户展示优先级越高),可以在筛选后追加排序逻辑:
let sortedMatchedPeople = matchedPeople.sorted { userA, userB in let matchCountA = userA.foodLikings.intersection(currentUser.foodLikings).count let matchCountB = userB.foodLikings.intersection(currentUser.foodLikings).count return matchCountA > matchCountB }
如果需要设置最低匹配阈值(比如至少有2个共同偏好才展示),只需要修改filter里的判断条件,把判断空改成判断交集数量大于等于阈值即可。
内容的提问来源于stack exchange,提问作者Swifter64
相关产品推荐
相关产品推荐

