Compare commits
1 Commits
main
...
word-regro
| Author | SHA1 | Date | |
|---|---|---|---|
|
52e9954c71
|
@@ -21,49 +21,83 @@ List<WordSearchResult> regroupWordSearchResults({
|
|||||||
}) {
|
}) {
|
||||||
final List<WordSearchResult> results = [];
|
final List<WordSearchResult> results = [];
|
||||||
|
|
||||||
final commonEntryIds = linearWordQueryData.commonEntries
|
final Set<int> commonEntryIds = linearWordQueryData.commonEntries
|
||||||
.map((entry) => entry['entryId'] as int)
|
.map((entry) => entry['entryId'] as int)
|
||||||
.toSet();
|
.toSet();
|
||||||
|
|
||||||
|
final Map<int, List<Map<String, Object?>>> entryReadingElementsByEntryId =
|
||||||
|
linearWordQueryData.readingElements.groupListsBy(
|
||||||
|
(element) => element['entryId'] as int,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, List<Map<String, Object?>>> entryKanjiElementsByEntryId =
|
||||||
|
linearWordQueryData.kanjiElements.groupListsBy(
|
||||||
|
(element) => element['entryId'] as int,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, int> elementIdToEntryId = {
|
||||||
|
for (final element in linearWordQueryData.readingElements)
|
||||||
|
element['elementId'] as int: element['entryId'] as int,
|
||||||
|
for (final element in linearWordQueryData.kanjiElements)
|
||||||
|
element['elementId'] as int: element['entryId'] as int,
|
||||||
|
};
|
||||||
|
|
||||||
|
final Map<int, List<Map<String, Object?>>> entryReadingElementInfosByEntryId =
|
||||||
|
linearWordQueryData.readingElementInfos.groupListsBy(
|
||||||
|
(element) => elementIdToEntryId[element['elementId'] as int]!,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, List<Map<String, Object?>>> entryKanjiElementInfosByEntryId =
|
||||||
|
linearWordQueryData.kanjiElementInfos.groupListsBy(
|
||||||
|
(element) => elementIdToEntryId[element['elementId'] as int]!,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, List<Map<String, Object?>>>
|
||||||
|
entryReadingElementRestrictionsByEntryId = linearWordQueryData
|
||||||
|
.readingElementRestrictions
|
||||||
|
.groupListsBy(
|
||||||
|
(element) => elementIdToEntryId[element['elementId'] as int]!,
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, JlptLevel> entryJlptTagsByEntryId = linearWordQueryData
|
||||||
|
.jlptTags
|
||||||
|
.groupSetsBy((element) => element['entryId'] as int)
|
||||||
|
.map(
|
||||||
|
(final key, final value) => MapEntry(
|
||||||
|
key,
|
||||||
|
value.map((e) => JlptLevel.fromString(e['jlptLevel'] as String?)).min,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, List<Map<String, Object?>>> entrySensesByEntryId =
|
||||||
|
linearWordQueryData.senses.groupListsBy(
|
||||||
|
(element) => element['entryId'] as int,
|
||||||
|
);
|
||||||
|
|
||||||
for (final scoredEntryId in entryIds) {
|
for (final scoredEntryId in entryIds) {
|
||||||
final List<Map<String, Object?>> entryReadingElements = linearWordQueryData
|
final List<Map<String, Object?>> entryReadingElements =
|
||||||
.readingElements
|
entryReadingElementsByEntryId[scoredEntryId.entryId] ?? const [];
|
||||||
.where((element) => element['entryId'] == scoredEntryId.entryId)
|
final List<Map<String, Object?>> entryKanjiElements =
|
||||||
.toList();
|
entryKanjiElementsByEntryId[scoredEntryId.entryId] ?? const [];
|
||||||
|
final List<Map<String, Object?>> entryReadingElementInfos =
|
||||||
final List<Map<String, Object?>> entryKanjiElements = linearWordQueryData
|
entryReadingElementInfosByEntryId[scoredEntryId.entryId] ?? const [];
|
||||||
.kanjiElements
|
final List<Map<String, Object?>> entryKanjiElementInfos =
|
||||||
.where((element) => element['entryId'] == scoredEntryId.entryId)
|
entryKanjiElementInfosByEntryId[scoredEntryId.entryId] ?? const [];
|
||||||
.toList();
|
final List<Map<String, Object?>> entryReadingElementRestrictions =
|
||||||
|
entryReadingElementRestrictionsByEntryId[scoredEntryId.entryId] ??
|
||||||
final List<Map<String, Object?>> entryJlptTags = linearWordQueryData
|
const [];
|
||||||
.jlptTags
|
|
||||||
.where((element) => element['entryId'] == scoredEntryId.entryId)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final jlptLevel =
|
|
||||||
entryJlptTags
|
|
||||||
.map((e) => JlptLevel.fromString(e['jlptLevel'] as String?))
|
|
||||||
.sorted((a, b) => b.compareTo(a))
|
|
||||||
.firstOrNull ??
|
|
||||||
JlptLevel.none;
|
|
||||||
|
|
||||||
final isCommon = commonEntryIds.contains(scoredEntryId.entryId);
|
|
||||||
|
|
||||||
final List<Map<String, Object?>> entrySenses = linearWordQueryData.senses
|
|
||||||
.where((element) => element['entryId'] == scoredEntryId.entryId)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final GroupedWordResult entryReadingElementsGrouped = _regroupWords(
|
final GroupedWordResult entryReadingElementsGrouped = _regroupWords(
|
||||||
entryId: scoredEntryId.entryId,
|
|
||||||
readingElements: entryReadingElements,
|
|
||||||
kanjiElements: entryKanjiElements,
|
kanjiElements: entryKanjiElements,
|
||||||
readingElementInfos: linearWordQueryData.readingElementInfos,
|
kanjiElementInfos: entryKanjiElementInfos,
|
||||||
readingElementRestrictions:
|
readingElements: entryReadingElements,
|
||||||
linearWordQueryData.readingElementRestrictions,
|
readingElementInfos: entryReadingElementInfos,
|
||||||
kanjiElementInfos: linearWordQueryData.kanjiElementInfos,
|
readingElementRestrictions: entryReadingElementRestrictions,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final List<Map<String, Object?>> entrySenses =
|
||||||
|
entrySensesByEntryId[scoredEntryId.entryId] ?? const [];
|
||||||
|
|
||||||
final List<WordSearchSense> entrySensesGrouped = _regroupSenses(
|
final List<WordSearchSense> entrySensesGrouped = _regroupSenses(
|
||||||
senses: entrySenses,
|
senses: entrySenses,
|
||||||
senseAntonyms: linearWordQueryData.senseAntonyms,
|
senseAntonyms: linearWordQueryData.senseAntonyms,
|
||||||
@@ -82,6 +116,10 @@ List<WordSearchResult> regroupWordSearchResults({
|
|||||||
senseAntonymsXrefData: linearWordQueryData.senseAntonymData,
|
senseAntonymsXrefData: linearWordQueryData.senseAntonymData,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final bool isCommon = commonEntryIds.contains(scoredEntryId.entryId);
|
||||||
|
final JlptLevel jlptLevel =
|
||||||
|
entryJlptTagsByEntryId[scoredEntryId.entryId] ?? JlptLevel.none;
|
||||||
|
|
||||||
results.add(
|
results.add(
|
||||||
WordSearchResult(
|
WordSearchResult(
|
||||||
score: scoredEntryId.score,
|
score: scoredEntryId.score,
|
||||||
@@ -113,7 +151,6 @@ class GroupedWordResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GroupedWordResult _regroupWords({
|
GroupedWordResult _regroupWords({
|
||||||
required int entryId,
|
|
||||||
required List<Map<String, Object?>> kanjiElements,
|
required List<Map<String, Object?>> kanjiElements,
|
||||||
required List<Map<String, Object?>> kanjiElementInfos,
|
required List<Map<String, Object?>> kanjiElementInfos,
|
||||||
required List<Map<String, Object?>> readingElements,
|
required List<Map<String, Object?>> readingElements,
|
||||||
@@ -122,36 +159,34 @@ GroupedWordResult _regroupWords({
|
|||||||
}) {
|
}) {
|
||||||
final List<WordSearchRuby> rubys = [];
|
final List<WordSearchRuby> rubys = [];
|
||||||
|
|
||||||
final kanjiElements_ = kanjiElements
|
final Map<int, Set<String>> readingElementRestrictionsSet =
|
||||||
.where((element) => element['entryId'] == entryId)
|
readingElementRestrictions
|
||||||
.toList();
|
.groupSetsBy((element) => element['elementId'] as int)
|
||||||
|
.map(
|
||||||
|
(key, value) => MapEntry(
|
||||||
|
key,
|
||||||
|
value.map((e) => e['restriction'] as String).toSet(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
final readingElements_ = readingElements
|
// Construct a cartesian product of kanji + readings, with exceptions made for items marked in `restrictions`.
|
||||||
.where((element) => element['entryId'] == entryId)
|
for (final readingElement in readingElements) {
|
||||||
.toList();
|
if (readingElement['doesNotMatchKanji'] == 1 || kanjiElements.isEmpty) {
|
||||||
|
|
||||||
final readingElementRestrictions_ = readingElementRestrictions
|
|
||||||
.where((element) => element['entryId'] == entryId)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
for (final readingElement in readingElements_) {
|
|
||||||
if (readingElement['doesNotMatchKanji'] == 1 || kanjiElements_.isEmpty) {
|
|
||||||
final ruby = WordSearchRuby(base: readingElement['reading'] as String);
|
final ruby = WordSearchRuby(base: readingElement['reading'] as String);
|
||||||
rubys.add(ruby);
|
rubys.add(ruby);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final kanjiElement in kanjiElements_) {
|
for (final kanjiElement in kanjiElements) {
|
||||||
final kanji = kanjiElement['reading'] as String;
|
final kanji = kanjiElement['reading'] as String;
|
||||||
final reading = readingElement['reading'] as String;
|
final reading = readingElement['reading'] as String;
|
||||||
|
|
||||||
final restrictions = readingElementRestrictions_
|
// The 'restrictions' act as an allowlist, meaning that non-matching kanji elements should be ignored.
|
||||||
.where((element) => element['reading'] == reading)
|
final restrictions =
|
||||||
.toList();
|
readingElementRestrictionsSet[readingElement['elementId'] as int] ??
|
||||||
|
{};
|
||||||
if (restrictions.isNotEmpty &&
|
if (restrictions.isNotEmpty && !restrictions.contains(kanji)) {
|
||||||
!restrictions.any((element) => element['restriction'] == kanji)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,35 +195,30 @@ GroupedWordResult _regroupWords({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rubys.isNotEmpty, 'No readings found for entryId: $entryId');
|
assert(
|
||||||
|
rubys.isNotEmpty,
|
||||||
|
'No readings found for entryId: ${kanjiElements.firstOrNull?['entryId'] ?? readingElements.firstOrNull?['entryId'] ?? '???'}',
|
||||||
|
);
|
||||||
|
|
||||||
final Map<int, String> readingElementIdsToReading = {
|
final Map<int, String> readingElementIdsToReading = {
|
||||||
for (final element in readingElements_)
|
for (final element in readingElements)
|
||||||
element['elementId'] as int: element['reading'] as String,
|
element['elementId'] as int: element['reading'] as String,
|
||||||
};
|
};
|
||||||
|
|
||||||
final Map<int, String> kanjiElementIdsToReading = {
|
final Map<int, String> kanjiElementIdsToReading = {
|
||||||
for (final element in kanjiElements_)
|
for (final element in kanjiElements)
|
||||||
element['elementId'] as int: element['reading'] as String,
|
element['elementId'] as int: element['reading'] as String,
|
||||||
};
|
};
|
||||||
|
|
||||||
final readingElementInfos_ = readingElementInfos
|
|
||||||
.where((element) => element['entryId'] == entryId)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final kanjiElementInfos_ = kanjiElementInfos
|
|
||||||
.where((element) => element['entryId'] == entryId)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return GroupedWordResult(
|
return GroupedWordResult(
|
||||||
rubys: rubys,
|
rubys: rubys,
|
||||||
readingInfos: {
|
readingInfos: {
|
||||||
for (final rei in readingElementInfos_)
|
for (final rei in readingElementInfos)
|
||||||
readingElementIdsToReading[rei['elementId'] as int]!:
|
readingElementIdsToReading[rei['elementId'] as int]!:
|
||||||
JMdictReadingInfo.fromId(rei['info'] as String),
|
JMdictReadingInfo.fromId(rei['info'] as String),
|
||||||
},
|
},
|
||||||
kanjiInfos: {
|
kanjiInfos: {
|
||||||
for (final kei in kanjiElementInfos_)
|
for (final kei in kanjiElementInfos)
|
||||||
kanjiElementIdsToReading[kei['elementId'] as int]!:
|
kanjiElementIdsToReading[kei['elementId'] as int]!:
|
||||||
JMdictKanjiInfo.fromId(kei['info'] as String),
|
JMdictKanjiInfo.fromId(kei['info'] as String),
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user