如何过滤视图中显示的数据?

Posted

技术标签:

【中文标题】如何过滤视图中显示的数据?【英文标题】:How do I filter my data displayed in my view? 【发布时间】:2022-01-23 22:58:52 【问题描述】:

下面的我的 XCODE Swift VIEW 代码显示了我的数据中所有 Flavor Groups 和 Descriptors 的列表。我想做的是过滤数据以显示所有风味组和描述符,除非 isSeltzer 为假。

我尝试在我的视图模型中使用类似的东西,然后在我的视图中使用过滤后的数组进行迭代,但我无法让它工作:

let flavorsNoSeltzers = flavors.filter( return $0.isSeltzer != false )

这是我的本地 JSON 数据示例:

    [
    
        "id": "562811",
        "flavorGroup": "APRICOT",
        "name": "NATURAL AND ARTIFICIAL APRICOT FLAVOR",
        "isBeer": true,
        "isSeltzer": false,
        "isArtificial": true,
        "descriptors": ["FRUITY"],
        "keywords": ["juicy", "skunky", "peach", "floral", "slight green (sierra nevada pale ale)"]
    ,
    
        "id": "U39252",
        "flavorGroup": "BANANA",
        "name": "NATURAL BANANA FLAVORING",
        "isBeer": true,
        "isSeltzer": true,
        "isArtificial": false,
        "descriptors": [""],
        "keywords": ["missing"]
    ,
    
        "id": "681686",
        "flavorGroup": "WHITE CHOCOLATE",
        "name": "NATURAL WHITE CHOCOLATE FLAVOR WONF",
        "isBeer": true,
        "isSeltzer": true,
        "isArtificial": false,
        "descriptors": ["LACTONIC", "COCOA", "CREAMY"],
        "keywords": ["nutty", "milk chocolate", "french vanilla", "custard", "cakey"]
    
]

这是我的模型的一个例子:

struct Flavor: Codable, Identifiable 
    enum CodingKeys: CodingKey 
        case id
        case flavorGroup
        case name
        case isBeer
        case isSeltzer
        case isArtificial
        case descriptors
        case keywords
    
    let id, flavorGroup, name: String
    let isBeer, isSeltzer, isArtificial: Bool
    let descriptors, keywords: [String]

这是我的视图模型的示例:

class ReadData: ObservableObject  
    @Published var flavors = [Flavor]()  
    init()
        loadData()
    
    func loadData()  
        guard let url = Bundle.main.url(forResource: "flavors", withExtension: "json")
            else 
                print("Json file not found")
                return
            
        let data = try? Data(contentsOf: url)
        let flavors = try? JSONDecoder().decode([Flavor].self, from: data!)
        self.flavors = flavors!
    

这是我的 VIEW 示例:

struct myView: View 
    @ObservedObject var flavorData = ReadData()
    var body: some View
        List(flavorData.flavors) flavor in
            VStack(alignment: .leading) 
                Text(flavor.flavorGroup)
                ForEach(flavor.descriptors, id: \.self)  descriptor in
                    if descriptor.isEmpty 
                        // do nothing
                     else 
                        Text("- \(descriptor)")
                    
                
            
        
    

【问题讨论】:

你的错误是什么? 【参考方案1】:

一个简化的工作示例,过滤Flavor 对象列表并返回一个仅包含Flavor 对象的新列表,其中isSeltzertrue

import Foundation

struct Flavor 
    let id: String
    let isSeltzer: Bool


let flavors = [Flavor(id: "First", isSeltzer: false), Flavor(id: "Second", isSeltzer: true), Flavor(id: "Third", isSeltzer: false)]
let flavorsSeltzersTrue = flavors.filter( $0.isSeltzer )

print(flavorsSeltzersTrue) // Prints the flavors with isSeltzer == true

如果你想要相反的(即isSeltzerfalse),你可以简单地将闭包中的$0.isSeltzer 更改为!$0.isSeltzer。另外,check out the documentation 在 filter(_:) 方法上。

如果这不能解决您的问题,那么您的代码还有其他问题。

编辑:

在您的代码中,您可能希望像这样添加这行代码:

class ReadData: ObservableObject  
    @Published var flavors = [Flavor]()  
    init()
        loadData()
    
    func loadData()  
        guard let url = Bundle.main.url(forResource: "flavors", withExtension: "json")
            else 
                print("Json file not found")
                return
            
        let data = try? Data(contentsOf: url)
        let flavors = try? JSONDecoder().decode([Flavor].self, from: data!)
        self.flavors = flavors.filter( $0.isSeltzer ) // I've added it here.
    

请注意,强制展开 (flavors!) 是不好的做法,当 flavorsnil 时可能会导致崩溃。

【讨论】:

我可以在您提供的简化工作示例中看到它是如何工作的。我的代码并不简单,因为我正在解析 JSON 数据。 (真正的 JSON 数据实际上有 3 条以上的记录)。在我提供的更复杂的代码示例中,我无法弄清楚在哪里以及如何将我的风味数组转换为过滤后的风味数组。 @MarkBurgun 我已更改答案并将其添加到您可能想要使用过滤器的位置。

以上是关于如何过滤视图中显示的数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?

如何过滤要在视图中显示的类型

如何使用 ICollectionView 过滤 wpf 树视图层次结构?

如何在 XPage 上配置 xe:viewFileItemService 以过滤分类视图中的数据?

如何过滤视图两列 OR 而不是 AND?

当用户使用 swift 的核心数据点击索引 0 到 1 时,如何显示不同的照片过滤器选项?