使用平面图进行搜索功能

Using flatmap for search function

我有一个加载到 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 [=12=].subSec.lowercased().contains(searchText.lowercased()) ? [=12=].subSec : nil }

        tableView.reloadData()
    }

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

附加代码:

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

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

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 { 
            [=11=].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 {
            [=12=].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 {
            [=13=].range(
                of: searchText, options: .caseInsensitive, range: nil, locale: nil
            ) != nil
        }
    }
}

您的错误可以通过map将所有小节改为小写来解决。

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

让我们用语言描述你想做什么:

flatten the sections so that I get a 1D array of all the subsections as strings

only keep those elements in the subsections that match the search string.

要完成第一件事,您需要 flatMap。要执行第二个操作,您需要 filter.

你不能为此使用单个平面图,因为你不能在平面图闭包中 return nil 来表示“摆脱这个”。

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

而不是

[=10=].subSec.lowercased().contains(searchText.lowercased())

你可以试试

[=11=].subSec.contains({[=11=].lowercased() == searchText.lowercased()})