2017-04-26 65 views
0

你好我试图在swift 3.0中实现搜索栏,它的部分完成,我没有得到预期的结果,这里是我得到的东西这样快速排序结果集取决于字符串的出现次数

enter image description here

这里结果是我的控制器

 class MasterViewController: UITableViewController 
     { 
    // MARK: - Properties 
     var detailViewController: DetailViewController? = nil 
    var candies = [Candy]() 
    var filteredCandies = [Candy]() 
    let searchController = UISearchController(searchResultsController: nil) 

// MARK: - Viewcontroller lifecycle 
override func viewDidLoad() 
{ 
    super.viewDidLoad() 
    setupSearchVC() 
    setupModelData() 
    if let splitViewController = splitViewController { 
     let controllers = splitViewController.viewControllers 
     detailViewController = (controllers[controllers.count - 1] as! UINavigationController).topViewController as? DetailViewController 
    } 
} 

override func viewWillAppear(_ animated: Bool) 
{ 
    clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed 
    super.viewWillAppear(animated) 
} 

// MARK: - View setup 
func setupSearchVC() 
{ 
    searchController.searchResultsUpdater = self 
    searchController.dimsBackgroundDuringPresentation = false 
    searchController.searchBar.scopeButtonTitles = ["All", "Chocolate", "Hard", "Other"] 
    searchController.searchBar.delegate = self 
    definesPresentationContext = true 
    tableView.tableHeaderView = searchController.searchBar 
} 


// MARK: - Segues 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
{ 
    if segue.identifier == "showDetail" 
    { 
     if let indexPath = tableView.indexPathForSelectedRow 
     { 
      let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController 
      controller.detailCandy = getDaCorrectCandyNow(row: indexPath.row) 
      controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem 
      controller.navigationItem.leftItemsSupplementBackButton = true 
     } 
    } 
} 

// MARK: - Controller responsibilities 
func setupModelData() 
{ 
    candies = [ 
     Candy(category:"complete", name:"test"), 
     Candy(category:"incomplete", name:"test test"), 

    ] 
} 


func getDaCorrectCandyNow(row: Int) -> Candy 
{ 
    let candy: Candy 
    if searchController.isActive { 
     candy = filteredCandies[row] 
    } else { 
     candy = candies[row] 
    } 
    return candy 
} 

func filterContentForSearchText(_ searchText: String, scope: String = "All") 
{ 
    filteredCandies = candies.filter { candy in 
     let categoryMatch = (scope == "All" ? true : (candy.category == scope)) 
     let searchValueIsNotEmpty = (categoryMatch && candy.name.lowercased().contains(searchText.lowercased()) || candy.category.lowercased().contains(searchText.lowercased())) 
     let searchValueIsEmpty = (searchText == "") 
     return searchValueIsEmpty ? categoryMatch : searchValueIsNotEmpty 
    } 
    tableView.reloadData() 
    } 
    } 

这里是我的tableview

 override func tableView(_ tableView: UITableView, 
     numberOfRowsInSection section: Int) -> Int 
      { 
      if searchController.isActive { 
     return filteredCandies.count 
      } 
    return candies.count 
} 



func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) 
    let candy: Candy = getDaCorrectCandyNow(row: indexPath.row) 
    cell.textLabel?.text = candy.name 
    cell.detailTextLabel?.text = candy.category 
    return cell 
} 


// MARK: - Search bar Delegate 
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) 
{ 
    print("*searchBar - ") 
    filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope]) 
} 

// MARK: - Search View Controller Delegate 
public func updateSearchResults(for searchController: UISearchController) 
{ 
    let searchBar = searchController.searchBar 
    print("*updateSearchResults - \(searchBar.text)") 
    let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex] 
    filterContentForSearchText(searchController.searchBar.text!, scope: scope) 
} 
} 

我希望我的结果以no号为基础显示。出现在我的结果集 为如 如果我在搜索栏 和 搜索“测试”如果我将结果集这样 集糖果= [ 糖果(类别:“完整”,名称:“测试”) , 糖果(类别:“不完整”,名称:“测试”)] 我想糖果(类别:“不完整”,名称:“测试测试”)首先显示,因为它有两个“测试”项目我如何去做?对不起我的英文,请提前致谢

回答

1

您需要做的是计算每个糖果上的匹配数并在将数据返回到filteredCandies数组之前对数据进行排序。要做到这一点,你需要修改你的过滤器功能。

你可以使用map()函数返回一个包含糖果和匹配计数的元组数组。

从那里你可以筛选匹配的数量和排序计数上的元组数组。然后,你只需从元组中移除count并仅返回最后一个数组中的糖果。

要计算匹配的数量,可以使用String类型的components()函数。使用搜索字符串作为components()的分隔符将返回比匹配数量多一个子字符串(因此count - 1将是匹配数)。

这里有一个如何,你可以使用这种方法写一个过滤器的例子:

filteredCandies = candies.map 
{ 
    candy in 

    let matchesCategory = scope == "All" || candy.category == scope 
    var matchCount  = matchesCategory ? 1 : 0 

    if matchesCategory && searchText != "" 
    { 
     let lowerSearch = searchText.lowercased() 
     matchCount = candy.name.lowercased().components(separatedBy: lowerSearch).count - 1 
     matchCount += candy.category.lowercased().components(separatedBy: lowerSearch).count - 1 
    } 

    return (candy,matchCount) 
} 
.filter{ $1 > 0 }.sorted{$0.1 > $1.1}.map{$0.0} 
+0

非常感谢你的队友,就像一个魅力。 –