as-services/libs/utils/words-id/autocorrect/BKNodePhonetic.js
devthejo 16b7e7d6aa
All checks were successful
/ build (map[dockerfile:./services/hasura/Dockerfile name:hasura]) (push) Successful in 47s
/ build (map[dockerfile:./services/web/Dockerfile name:web]) (push) Successful in 1m47s
/ build (map[dockerfile:./services/watchers/Dockerfile name:watchers]) (push) Successful in 2m37s
/ build (map[dockerfile:./services/files/Dockerfile name:files]) (push) Successful in 2m52s
/ build (map[dockerfile:./services/api/Dockerfile name:api]) (push) Successful in 3m2s
/ build (map[dockerfile:./services/app/Dockerfile name:app]) (push) Successful in 31s
/ build (map[dockerfile:./services/tasks/Dockerfile name:tasks]) (push) Successful in 2m44s
/ deploy (push) Successful in 48s
chore(init): available sources
2025-04-13 10:46:53 +02:00

66 lines
1.6 KiB
JavaScript

const levenshtein = require("fast-levenshtein")
const toPhonetic = require("talisman/phonetics/french/phonetic")
module.exports = class BKNodePhonetic {
static toPhonetic(word) {
return toPhonetic(word)
}
constructor(word, phonetic) {
this.word = word
if (!phonetic) {
phonetic = BKNodePhonetic.toPhonetic(word)
}
this.phonetic = phonetic
this.children = new Map()
}
insert(otherWord, phonetic) {
if (!phonetic) {
phonetic = BKNodePhonetic.toPhonetic(otherWord)
}
const dist = levenshtein.get(this.phonetic, phonetic)
if (this.children.has(dist)) {
this.children.get(dist).insert(otherWord, phonetic)
} else {
this.children.set(dist, new BKNodePhonetic(otherWord, phonetic))
}
}
search(target, phoneticTarget, maxDist) {
if (!phoneticTarget) {
phoneticTarget = BKNodePhonetic.toPhonetic(target)
}
const currentDist = levenshtein.get(this.phonetic, phoneticTarget)
// Early stopping if a close match is found
if (currentDist <= maxDist) {
return { word: this.word, distance: currentDist }
}
let minDistanceWord = null
for (
let i = Math.max(0, currentDist - maxDist);
i <= currentDist + maxDist;
i++
) {
if (this.children.has(i)) {
const result = this.children
.get(i)
.search(target, phoneticTarget, maxDist)
if (
result &&
(!minDistanceWord || result.distance < minDistanceWord.distance)
) {
minDistanceWord = result
if (result.distance <= 1) {
break
}
}
}
}
return minDistanceWord
}
}