Фильтр с учетом регистра, доступный для поиска, в массиве строк.

У меня есть массив строк внутри структуры. Это заполняет список, и я использую .searchable для фильтрации элементов. Я могу фильтровать их по тексту, дате или тегам внутри каждого элемента. Все сделано без оглядки на случай.

Теперь, что касается тегов, я изо всех сил пытаюсь найти правильный способ их фильтрации:

let dateFormatter = DateFormatter()

struct LibItem: Codable, Hashable, Identifiable {
    let id: UUID
    var text: String
    var date = Date()
    var dateText: String {
        dateFormatter.dateFormat = "EEEE, MMM d yyyy, h:mm a"
        return dateFormatter.string(from: date)
    }
    var tags: [String] = []
}

final class DataModel: ObservableObject {
    @AppStorage("myapp") public var collectables: [LibItem] = []

    init() {
        self.collectables = self.collectables.sorted(by: {
            $0.date.compare($1.date) == .orderedDescending
        })
    }

    func sortList() {
        self.collectables = self.collectables.sorted(by: {
            $0.date.compare($1.date) == .orderedDescending
        })
    }    
}

struct ContentView: View {
    @EnvironmentObject private var data: DataModel
    @State var searchText: String = ""

    var body: some View {
        NavigationView {
            List(filteredItems) { collectable in
                VStack(alignment: .leading) {
                    Spacer()
                    Text(collectable.text).font(.body).padding(.leading).padding(.bottom, 1)
                    Spacer()
                }
            }
            .listStyle(.plain)
            .searchable(
                text: $searchText,
                placement: .navigationBarDrawer(displayMode: .always),
                prompt: "Search..."
            )
        } 
    }

    var filteredItems: [LibItem] {       
        switch selectedItem {
        case 1: // date
            return data.collectables.filter {
                searchText.isEmpty ? true : $0.dateText.localizedCaseInsensitiveContains(searchText)
            }
        case 2: //tags <--- here how do I search and filter by, case insensitive?
            return data.collectables.filter {
                searchText.isEmpty ? true : $0.tags.contains(searchText)
            }
        default:
            return data.collectables.filter {
                searchText.isEmpty ? true : $0.text.localizedCaseInsensitiveContains(searchText)
            }
        }

    }
}
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
0
22
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Сравните две строчные строки, на мгновение превратив обе стороны сравнения в нижний регистр.

Пример, который вы можете использовать в своем коде:

$0.tags.compactMap { $0.lowercased() }.contains(searchText.lowercased())

Если вам нужно проверить, содержит ли каждый отдельный элемент tagsчасть строки, вам нужно повторить:

var isTagFound = false
$0.tags.compactMap { $0.lowercased() }.forEach {
    if $0.contains(searchText.lowercased()) {
        isTagFound = true
    }
}

Спасибо. Это работает, если условием поиска является тег точно. Любой способ сопоставить любую часть слова? Я как я сделал с текстом и датами?

Aleph 10.04.2022 19:52

@Aleph: только что отредактировал ответ.

HunterLion 10.04.2022 19:53
Ответ принят как подходящий

Для строгого равенства без учета регистра:

return data.collectables.filter {
   searchText.isEmpty
      ? true
      : $0.tags.contains { tag in tag.caseInsensitiveCompare(searchText) == .orderedSame }
}

для подстрок вы можете использовать метод range(of:):

return data.collectables.filter {
   searchText.isEmpty
      ? true
      : $0.tags.contains { tag in tag.range(of: searchText, options: .caseInsensitive) != nil }
}

или используйте localizedCaseInsensitiveContains, который вы уже использовали ранее:

return data.collectables.filter {
   searchText.isEmpty
      ? true
      : $0.tags.contains { tag in tag.localizedCaseInsensitiveContains(searchText) }
}
range(of:) сработало отлично, спасибо.
Aleph 10.04.2022 20:02

Другие вопросы по теме