From f159b39c89c4083c4ca9efd57e540cfc14147771 Mon Sep 17 00:00:00 2001 From: Stefan Vukovic Date: Tue, 9 Jan 2024 09:38:14 +0100 Subject: [PATCH] use Map in areArraysEqualIgnoreOrder --- ext/js/dictionary/dictionary-data-util.js | 8 +++--- ext/js/language/translator.js | 35 +++++++++++++++++++---- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/ext/js/dictionary/dictionary-data-util.js b/ext/js/dictionary/dictionary-data-util.js index c27e377e86..50ae4b1194 100644 --- a/ext/js/dictionary/dictionary-data-util.js +++ b/ext/js/dictionary/dictionary-data-util.js @@ -331,8 +331,8 @@ export class DictionaryDataUtil { const pitchAccent2 = /** @type {import('dictionary').PitchAccent} */ (pronunciation2); return ( pronunciation1.position === pitchAccent2.position && - this.areArraysEqual(pronunciation1.nasalPositions, pitchAccent2.nasalPositions) && - this.areArraysEqual(pronunciation1.devoicePositions, pitchAccent2.devoicePositions) + this._areArraysEqual(pronunciation1.nasalPositions, pitchAccent2.nasalPositions) && + this._areArraysEqual(pronunciation1.devoicePositions, pitchAccent2.devoicePositions) ); } case 'phonetic-transcription': @@ -351,7 +351,7 @@ export class DictionaryDataUtil { * @param {T[]} array2 * @returns {boolean} */ - static areArraysEqual(array1, array2) { + static _areArraysEqual(array1, array2) { const ii = array1.length; if (ii !== array2.length) { return false; } for (let i = 0; i < ii; ++i) { @@ -372,7 +372,7 @@ export class DictionaryDataUtil { for (let i = 0; i < ii; ++i) { const tag1 = tagList1[i]; const tag2 = tagList2[i]; - if (tag1.name !== tag2.name || !this.areArraysEqual(tag1.dictionaries, tag2.dictionaries)) { + if (tag1.name !== tag2.name || !this._areArraysEqual(tag1.dictionaries, tag2.dictionaries)) { return false; } } diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js index afc40d19b2..23a7bfc2a4 100644 --- a/ext/js/language/translator.js +++ b/ext/js/language/translator.js @@ -16,7 +16,6 @@ * along with this program. If not, see . */ -import {DictionaryDataUtil} from '../dictionary/dictionary-data-util.js'; import {RegexUtil} from '../general/regex-util.js'; import {TextSourceMap} from '../general/text-source-map.js'; import {Deinflector} from './deinflector.js'; @@ -249,7 +248,6 @@ export class Translator { } /** - * * @param {import('dictionary').TermDictionaryEntry} existingEntry * @param {import('dictionary').InflectionHypothesis[]} inflectionHypotheses */ @@ -257,10 +255,7 @@ export class Translator { const existingHypotheses = existingEntry.inflectionHypotheses; for (const {source, inflections} of inflectionHypotheses) { - const duplicate = existingHypotheses.find((hypothesis) => DictionaryDataUtil.areArraysEqual( - [...hypothesis.inflections].sort(), - [...inflections].sort() - )); + const duplicate = existingHypotheses.find((hypothesis) => this._areArraysEqualIgnoreOrder(hypothesis.inflections, inflections)); if (!duplicate) { existingEntry.inflectionHypotheses.push({source, inflections}); } else if (duplicate.source !== source) { @@ -269,6 +264,34 @@ export class Translator { } } + /** + * @param {string[]} array1 + * @param {string[]} array2 + * @returns {boolean} + */ + _areArraysEqualIgnoreOrder(array1, array2) { + if (array1.length !== array2.length) { + return false; + } + + const frequencyCounter = new Map(); + + for (const element of array1) { + frequencyCounter.set(element, (frequencyCounter.get(element) || 0) + 1); + } + + for (const element of array2) { + const frequency = frequencyCounter.get(element); + if (!frequency) { + return false; + } + frequencyCounter.set(element, frequency - 1); + } + + return true; + } + + /** * @param {string} text * @param {Map} enabledDictionaryMap