You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 12:59:56