使用flatmap进行搜索功能

时间:2017-08-26 11:34:11

标签: swift uisearchbar flatmap

我有一个加载到TableView中的数组。

var sections = [

        Section(sec: "One",
                subSec: ["A", "B", "C", "D", "E"],
                expanded: false),

        Section(sec: "Two",
                subSec: ["A", "B", "C", "D", "E"],
                expanded: false),

        Section(sec: "Three",
                subSec: ["A", "B", "C", "D", "E"],
                expanded: false),

以下是各部分的定义:

struct Section {
    var sec: String!
    var subSec: [String]! // [ ] = Array of Strings
    var expanded: Bool!

    init(sec: String, subSec: [String], expanded: Bool) {
        self.sec = sec
        self.subSec = subSec
        self.expanded = expanded
    }
}

我正在尝试构建搜索功能。它适用于标准数组,但不适用于我的变量,因为它更复杂。 我(在帮助下)使用flatmap调整了代码,但我不知道如何将它映射到subSec字符串。

func filterContentForSearchText(_ searchText: String, scope: String = "All") {
        filtered = sections.flatMap{ return $0.subSec.lowercased().contains(searchText.lowercased()) ? $0.subSec : nil }

        tableView.reloadData()
    }

我目前收到的错误是:Value type [String] has no value lowercased

附加代码:

var filtered = [Section]()
let searchController = UISearchController(searchResultsController: nil)

3 个答案:

答案 0 :(得分:1)

检查字符串是否包含另一个忽略大小写

的字符串
baseText.range(
    of: searchText, options: .caseInsensitive, range: nil, locale: nil
) != nil

代码

如果您想获得整个部分,那么您不需要使用flatMap,只需使用filter

var filtered: [Section] = []

func filterContentForSearchText(_ searchText: String, scope: String = "All") {
    filtered = sections.filter { section in
        section.subSec.contains { 
            $0.range(
                of: searchText, options: .caseInsensitive, range: nil, locale: nil
            ) != nil 
        }
    }
}

但是如果在该部分中您只想要那些包含搜索文本的子部分,那么

var filtered: [Section] = []

func filterContentForSearchText(_ searchText: String, scope: String = "All") {
    filtered = sections.map { section in
        var section = section
        section.subSec = section.subSec.filter {
            $0.range(
                of: searchText, options: .caseInsensitive, range: nil, locale: nil
            ) != nil
        }
        return section
    }
}

但如果你只想要小节,那么

var filtered: [String] = []

func filterContentForSearchText(_ searchText: String, scope: String = "All") {
    filtered = sections.flatMap { section in
        section.subSec.filter {
            $0.range(
                of: searchText, options: .caseInsensitive, range: nil, locale: nil
            ) != nil
        }
    }
}

答案 1 :(得分:0)

您的错误可以通过map ping所有小节来解决。

但是,这会给你一个[[String]]而不是[String],结果不是你想要的。

让我们用文字描述你想要做的事情:

  

展平sections,以便我将所有子部分的一维数组作为字符串

     

仅将这些元素保留在与搜索字符串匹配的子部分中。

要做第一件事,你需要flatMap。要做到第二步,您需要filter

你不能使用单个平面地图,因为你不能在平面地图封闭中返回nil来说“摆脱这个”。

let filtered: [String] = 
    sections.flatMap { $0.subSec }
             .filter { $0.lowercased().contains(searchText.lowercased()) }

答案 2 :(得分:0)

而不是

$0.subSec.lowercased().contains(searchText.lowercased())

你可以尝试

$0.subSec.contains({$0.lowercased() == searchText.lowercased()})