如何用SwiftData @Query获取Topic模型category列的唯一值数组
SwiftData 获取去重Category列的实现方案
直接用@Query var categories: [\Topic.category]这种写法行不通,@Query仅能返回完整的模型对象数组,没法直接提取单个属性的去重集合,下面提供两种可行实现方式:
方式一:全量查询后处理(简单直观)
先通过@Query获取所有Topic实例,再借助集合去重并提取category字段:
import SwiftUI import SwiftData struct CategoryListView: View { @Environment(\.modelContext) private var modelContext @Query private var allTopics: [Topic] // 计算属性生成去重排序后的category列表 private var uniqueCategories: [String] { Array(Set(allTopics.map(\.category))).sorted() } var body: some View { List(uniqueCategories, id: \.self) { category in Text(category) } } }
方式二:自定义FetchDescriptor查询(性能更优)
如果数据量较大,全量查询再处理会浪费性能,可使用FetchDescriptor指定仅查询category字段并开启去重:
import SwiftUI import SwiftData struct CategoryListView: View { @Environment(\.modelContext) private var modelContext @State private var uniqueCategories: [String] = [] var body: some View { List(uniqueCategories, id: \.self) { category in Text(category) } .task { // 构造查询描述符:只取category字段,并且去重 let fetchDescriptor = FetchDescriptor<Topic>( properties: [\.category], distinct: true ) do { // 执行查询,结果是包含category的元组数组,提取后转成字符串数组 let queryResults = try modelContext.fetch(fetchDescriptor) uniqueCategories = queryResults.compactMap { $0.category } } catch { print("查询category失败:\(error.localizedDescription)") } } } }
补充说明
- 若需要实时响应数据变化,方式二可结合
modelContext的监听事件,在数据更新时重新执行查询 - 方式一优势是代码简单,适合数据量小的场景;方式二更高效,适合大数据量场景
内容的提问来源于stack exchange,提问作者user2926337
相关产品推荐
相关产品推荐

