修复跨分类同名单词 ID 冲突,将 Word.id 从纯单词改为分类/单词组合

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 22:38:25 +08:00
parent 5b43882582
commit 5ed8a1fe4c
4 changed files with 22 additions and 11 deletions
@@ -151,7 +151,7 @@ enum NumberWords {
static func randomWord() -> Word {
let n = Int.random(in: 0...999_999_999)
return Word(word: english(n),
return Word(categoryId: "numbers", word: english(n),
phonetic: "/\(phonetic(n))/",
meaning: chinese(n),
example: "The number is \(english(n)).",
@@ -163,7 +163,7 @@ enum NumberWords {
}
private static func makeWord(_ n: Int) -> Word {
Word(word: english(n),
Word(categoryId: "numbers", word: english(n),
phonetic: "/\(phonetic(n))/",
meaning: chinese(n),
example: "I can count to \(english(n)).",
+2 -1
View File
@@ -13,7 +13,8 @@ struct WordCategory: Codable, Identifiable, Hashable {
}
struct Word: Codable, Identifiable, Hashable {
var id: String { word }
var id: String { "\(categoryId)/\(word)" }
var categoryId: String = ""
let word: String
let phonetic: String
let meaning: String
@@ -28,10 +28,20 @@ final class WordStore {
let data = try Data(contentsOf: url)
let decoded = try JSONDecoder().decode(WordBank.self, from: data)
let categories = decoded.categories.map { category -> WordCategory in
guard category.id == "numbers" else { return category }
var words = NumberWords.makeWords(atoms: category.words)
let extras = category.words.filter { NumberWords.atomNumbers[$0.word] == nil }
words.append(contentsOf: extras)
let tagged: [Word]
if category.id == "numbers" {
var words = NumberWords.makeWords(atoms: category.words)
let extras = category.words.filter { NumberWords.atomNumbers[$0.word] == nil }
words.append(contentsOf: extras)
tagged = words
} else {
tagged = category.words
}
let words = tagged.map { word -> Word in
var w = word
w.categoryId = category.id
return w
}
return WordCategory(id: category.id, name: category.name, icon: category.icon,
words: words)
}
@@ -52,8 +52,8 @@ final class QuizViewController: UIViewController {
self.isUppercase = uppercase
let words = config.words.map { word in
let text = uppercase ? word.word.uppercased() : word.word.lowercased()
return Word(word: text, phonetic: word.phonetic, meaning: word.meaning,
example: word.example, exampleMeaning: word.exampleMeaning)
return Word(categoryId: word.categoryId, word: text, phonetic: word.phonetic,
meaning: word.meaning, example: word.example, exampleMeaning: word.exampleMeaning)
}
self.questions = QuizGenerator.makeQuestions(mode: config.mode, words: words)
super.init(nibName: nil, bundle: nil)
@@ -509,8 +509,8 @@ final class QuizViewController: UIViewController {
view.subviews.compactMap { $0 as? QuizResultView }.forEach { $0.removeFromSuperview() }
let words = config.words.map { word in
let text = isUppercase ? word.word.uppercased() : word.word.lowercased()
return Word(word: text, phonetic: word.phonetic, meaning: word.meaning,
example: word.example, exampleMeaning: word.exampleMeaning)
return Word(categoryId: word.categoryId, word: text, phonetic: word.phonetic,
meaning: word.meaning, example: word.example, exampleMeaning: word.exampleMeaning)
}
questions = QuizGenerator.makeQuestions(mode: config.mode, words: words)
currentIndex = 0