Swift 搜索对象

Swift Search Objects

我想创建一个搜索功能,以便用户能够在我的应用程序中搜索列表。

我这样初始化这个赛道列表:

 var tracks: [Track] = tracksData

并像这样执行搜索:

NavigationSearch(text: $searchText, searchResultsContent: {
                VStack(alignment: .leading) {
                    Text("Search Results for \(searchText)")
                        .fontWeight(.bold)
                        .padding([.top, .bottom])

                    Divider()
                    
                    ForEach(Track.filter { self.searchText.isEmpty ? true : [=12=].contains(self.searchText) }, id: \.self) { fruit in
                        Text(fruit)
                        Divider()
                    }

                    Spacer()
                }
                .padding()
            })

这是来自 Mark van Wijnen 的 medium article

但我总是收到如下所示的错误:

我知道这个错误是由我用于跟踪对象的数据类型引起的,因为 Mark van Wijnen 使用了一个简单的字符串数组,但我无法修复此搜索功能以便它能够搜索我的对象数组。我希望有人好心帮我解决这个问题。 提前致谢

Link 到包含示例数据的包: https://workupload.com/file/cbky5ucgM26

你们太亲密了!将代码分开会产生更好的错误,并且您会发现它。如果将 self 用作 id,ForEach 要求该项目是可散列的。在 self 中使用 Track 的 id 属性 可能会清除该错误。然而,它需要一些工作才能实现,所以这里是重构代码。

将搜索过滤器分解为 TrackModel,以便可以搜索多个字段:

func search(_ query: String) -> Bool {
    let searchable = [title, headline, description] + details

    return searchable.filter({ [=10=].contains(query) }).count > 0
}

接下来在TrackView3中添加一个计算出来的属性来封装列表:

var filtered : [Track] {
    if searchText.isEmpty {
        return tracks
    } else {
        return tracks.filter({ [=11=].search(searchText) })
    }
}

现在 ForEach 没有所有搜索内容及其整洁的形式:

ForEach(filtered, id: \.id) { track in
 TrackDetailView(tracks: track)
 Divider()

}

Paul Hudson 最近制作了一个视频,其中包含提高 Swift 观看次数的技巧。他介绍了在计算属性中封装代码。它使代码更清晰,并使编码器免于声明树中的错误(错误并不总是有帮助)。 5 Steps to Better SwiftUI Views