我想搜索名称键的练习字典,然后在表格视图中显示过滤结果。我正在使用这个功能
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let filtered = exercises.filter { $0["name"] == searchText }
print(filtered)
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.exercisesTableView.reloadData()
}
变量:
var exercises = [Exercise]()
var filtered: [NSMutableArray] = []
var searchActive: Bool = false
在搜索功能中,我收到错误
Type'Exercise'没有下标成员
然后我遇到的问题是结果是NSMutableArray,因此我无法将结果名称设置为要显示的单元格文本
无法将'NSMutableArray'类型的值转换为强制中的'String'类型
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if (searchActive){
cell.textLabel?.text = filtered[indexPath.row] as String
} else {
let exercise = exercises[indexPath.row]
cell.textLabel!.text = exercise.name
}
return cell
}
这是我的练习词典供参考:
final public class Exercise {
var id: Int
var descrip: String
var name: String
var muscles: [Int]
var equipment: [Int]
public init?(dictionary: [String: Any]) {
guard
let id = dictionary["id"] as? Int,
let descrip = dictionary["description"] as? String,
let name = dictionary["name"] as? String,
let muscles = dictionary["muscles"] as? [Int],
let equipment = dictionary["equipment"] as? [Int]
else { return nil }
self.id = id
self.descrip = descrip
self.name = name
self.muscles = muscles
self.equipment = equipment
}
我可以通过使var过滤来修复第二个错误:[String] = []所以它可以用作单元格标题,但是这并不能解决第一个错误,我不确定是不是正确的方法呢?
答案 0 :(得分:6)
您的filtered
也是[Exercise]
类型,您需要过滤它。
var filtered = [Exercise]()
self.filtered = exercises.filter { $0.name == searchText }
此处$0
是Exercise
对象的类型,因此您需要使用$0.name
访问其属性名称。
修改:如果您希望filtered
仅包含[String]
类型的名称,那么您可能需要同时使用map
和filter
此
self.filtered = exercises.filter { $0.name == searchText }.map { $0.name }
OR
self.filtered = exercises.map { $0.name }.filter { $0 == searchText }
或者直接使用filterMap
作为@dfri建议。
self.filtered = exercises.flatMap{ $0.name == searchText ? $0.name : nil }
答案 1 :(得分:3)
我在昨天告诉你在使用自定义类时忘记了词典语义 不要使用密钥下载!
如其他答案中所述,您必须将var observableModule = require("data/observable")
var ObservableArray = require("data/observable-array").ObservableArray;
var arrNoticias = require('./home-view-model.js');
console.log(arrNoticias.getItem(0).titulo);
也声明为filtered
[Exercise]
并过滤
var filtered = [Exercise]()
但是,如果您还要搜索部分字符串,请使用
self.filtered = exercises.filter { $0.name == searchText }
<强>但是强>
由于过滤和未过滤的数组都是self.filtered = exercises.filter {$0.name.range(of: searchText, options: [.anchored, .caseInsensitive, .diacriticInsensitive]) != nil }
类型,您必须以这种方式更改[Exercise]
cellForRowAtIndexPath
答案 2 :(得分:0)
此处的问题是https://localhost:8243/authorize
https://localhost:8243/token
。在此上下文中,$0["name"] == searchText
属于$0
类型,您可以将其称为数组。这一行应如下所示:
Excersise
答案 3 :(得分:0)
就我而言,我在某些个人项目中使用了以下代码,该代码与先前的答案非常相似。我只使用contains
。
func filter(query: String){
if query.isEmpty {
self.filteredData = self.originalData
} else {
self.filteredData = self.originalData.filter {
$0.prop1!.lowercased().contains(query)
}
}
}
答案 4 :(得分:0)
在您的课程中声明以下数组:
var filteredData: [Exercise] = []
{
didSet
{
tableView.reloadData()
}
}
// once we get our data, we will put it into filtered array
// user will interact only with filtered array
var source: [Exercise] = []
{
didSet
{
filteredData = source
}
}
实现以下功能:
extension ViewController: UISearchBarDelegate
{
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
{
let searchText = searchText.lowercased()
let filtered = source.filter({ $0.lowercased().contains(searchText) })
filteredData = filtered.isEmpty ? source : filtered
}
}
您会注意到,用户永远不会与原始数组进行交互,而只会与过滤后的数组进行交互。
// MARK: UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return filteredData.count
}
// MARK: UITableViewDelegate
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
.
.
cell.textLabel?.text = filteredData[indexPath.row]
}