Add searchable instrument browser
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import Foundation
|
||||
|
||||
public struct LocalInstrumentCatalog: Sendable {
|
||||
public let items: [InstrumentCatalogItem]
|
||||
|
||||
@@ -5,6 +7,18 @@ public struct LocalInstrumentCatalog: Sendable {
|
||||
self.items = items
|
||||
}
|
||||
|
||||
public func instruments(matching query: String) -> [InstrumentCatalogItem] {
|
||||
let searchTokens = Self.searchTokens(for: query)
|
||||
|
||||
return items
|
||||
.filter { item in
|
||||
searchTokens.isEmpty || searchTokens.allSatisfy { token in
|
||||
Self.searchableTerms(for: item).contains { $0.contains(token) }
|
||||
}
|
||||
}
|
||||
.sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending }
|
||||
}
|
||||
|
||||
public static let worldwideItems: [InstrumentCatalogItem] =
|
||||
western + middleEastern + african + southAsian + eastAsian + southeastAsian + latinAmerican + folkAndModern
|
||||
|
||||
@@ -281,4 +295,23 @@ public struct LocalInstrumentCatalog: Sendable {
|
||||
searchTerms: terms
|
||||
)
|
||||
}
|
||||
|
||||
private static func searchableTerms(for item: InstrumentCatalogItem) -> [String] {
|
||||
searchTokens(for: [item.name] + item.aliases + item.searchTerms)
|
||||
}
|
||||
|
||||
private static func searchTokens(for query: String) -> [String] {
|
||||
searchTokens(for: [query])
|
||||
}
|
||||
|
||||
private static func searchTokens(for values: [String]) -> [String] {
|
||||
values
|
||||
.joined(separator: " ")
|
||||
.folding(
|
||||
options: [.caseInsensitive, .diacriticInsensitive, .widthInsensitive],
|
||||
locale: Locale(identifier: "en_US_POSIX")
|
||||
)
|
||||
.split(whereSeparator: { $0.isWhitespace || $0 == "-" })
|
||||
.map(String.init)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user