added prefix search!

added allitems
This commit is contained in:
neon443
2025-11-03 14:54:12 +00:00
parent 38b4ba4aa7
commit 3200b3cca3
2 changed files with 65 additions and 10 deletions

View File

@@ -16,6 +16,7 @@ class TrieNode: ObservableObject {
class Trie: ObservableObject { class Trie: ObservableObject {
@Published var root: TrieNode = TrieNode() @Published var root: TrieNode = TrieNode()
@Published var allItems: [String] = []
func insert(word: String) { func insert(word: String) {
let word = word.lowercased() let word = word.lowercased()
@@ -25,18 +26,16 @@ class Trie: ObservableObject {
for i in indices { for i in indices {
let char = word[i] let char = word[i]
if let node = currentNode.children[char] { if let node = currentNode.children[char] {
print("node \(char) exists")
currentNode = node currentNode = node
} else { } else {
print("node \(char) didnt exist creating")
currentNode.children[char] = TrieNode() currentNode.children[char] = TrieNode()
currentNode = currentNode.children[char]! currentNode = currentNode.children[char]!
if i == indices.last { }
print("marking \(char) as end of word") if i == indices.last {
currentNode.isEndOfWord = true currentNode.isEndOfWord = true
}
} }
} }
self.allItems.append(word)
} }
func search(for query: String) -> Bool { func search(for query: String) -> Bool {
@@ -51,9 +50,37 @@ class Trie: ObservableObject {
} }
return currentNode.isEndOfWord return currentNode.isEndOfWord
} }
func search(prefix prefixQuery: String) -> [String] {
guard !prefixQuery.isEmpty else { return allItems }
let prefixQuery = prefixQuery.lowercased()
var currentNode = root
for char in prefixQuery {
guard let child = currentNode.children[char] else {
return []
}
currentNode = child
}
return collectWords(startingWith: prefixQuery, from: currentNode)
}
func collectWords(startingWith: String, from node: TrieNode) -> [String] {
var results: [String] = []
if node.isEndOfWord {
results.append(startingWith)
}
for child in node.children {
results += collectWords(startingWith: startingWith+String(child.key), from: child.value)
}
return results
}
} }
struct TrieTestingView: View { struct TrieTestingView: View {
@ObservedObject var hoarder: EmojiHoarder = EmojiHoarder(localOnly: true)
@ObservedObject var trie: Trie = Trie() @ObservedObject var trie: Trie = Trie()
@State var id: UUID = UUID() @State var id: UUID = UUID()
@@ -63,8 +90,19 @@ struct TrieTestingView: View {
@State var searchTerm: String = "" @State var searchTerm: String = ""
@State var searchStatus: Bool? = nil @State var searchStatus: Bool? = nil
@State var filterTerm: String = ""
@State var filterResult: [String] = []
var body: some View { var body: some View {
VStack { VStack {
Button("add emojis!") {
for name in hoarder.emojis.map({ $0.name }) {
trie.insert(word: name)
}
print("done!")
}
.buttonStyle(.borderedProminent)
TextField("", text: $newWord) TextField("", text: $newWord)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
.border(.red) .border(.red)
@@ -85,12 +123,23 @@ struct TrieTestingView: View {
.foregroundStyle(searchStatus ? .green : .red) .foregroundStyle(searchStatus ? .green : .red)
} }
TextField("", text: $filterTerm)
.textFieldStyle(.roundedBorder)
.border(.orange)
.onChange(of: filterTerm) { _ in
filterResult = trie.search(prefix: filterTerm)
}
List(filterResult, id: \.self) { item in
Text(item)
}
// .id(id)
Text("\(trie.root.children.count)") Text("\(trie.root.children.count)")
List { // List {
TrieNodeView(trieNode: trie.root) // TrieNodeView(trieNode: trie.root)
} // }
.id(id) // .id(id)
} }
} }
} }

View File

@@ -16,6 +16,12 @@ struct ContentView: View {
var body: some View { var body: some View {
NavigationView { NavigationView {
List { List {
NavigationLink("trieTester") {
TrieTestingView(
hoarder: hoarder,
)
}
Button("none") { Button("none") {
hoarder.filterEmojis(byCategory: .none, searchTerm: searchTerm) hoarder.filterEmojis(byCategory: .none, searchTerm: searchTerm)
} }