diff options
| author | Geo Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2024-04-12 18:31:00 +0300 |
|---|---|---|
| committer | Geo Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2024-04-12 18:31:00 +0300 |
| commit | b122279ece06a9381e805c6087f130b41616fe3d (patch) | |
| tree | 2ec0a8fc3c570417d972b18a7a7b878758ce3a6f /utils/match-util.js | |
| parent | 762d85c95690f510bec4dd8c37c05454ae1be4fc (diff) | |
| download | oseine-b122279ece06a9381e805c6087f130b41616fe3d.tar.gz oseine-b122279ece06a9381e805c6087f130b41616fe3d.tar.bz2 oseine-b122279ece06a9381e805c6087f130b41616fe3d.zip | |
added utils folder; added several suplamentary modules
Diffstat (limited to 'utils/match-util.js')
| -rw-r--r-- | utils/match-util.js | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/utils/match-util.js b/utils/match-util.js new file mode 100644 index 0000000..a13fddb --- /dev/null +++ b/utils/match-util.js @@ -0,0 +1,92 @@ +/** Ngram fuzzy match algorithm + * (simple and fast) + */ +const createNgram = (word, n) => { // Ngram creation + if (word.length <3) return word; + const vector = []; + for (let i = 0; i < word.length-n+1; ++i) { + vector.push(word.slice(i, i + n)); + } + return vector; +}; + +/** similarity + * rates similarity between 2 words + * based on Ngram matches of N = n letters; + * implements a 2-dim check (all a-Ngrams vs all all b-Ngrams) + * + * @param {string} a : first word + * @param {string} b : second word + * @param {int} n : Ngram base + * @returns {float} : match percentage as a float in [0, 1] + */ +const similarity = (a, b, n) => { // Ngram match score + if (a.length > 0 && b.length > 0) { + const aNgram = createNgram(a, n); + const bNgram = createNgram(b, n); + let hits = 0; + for (let x = 0; x < aNgram.length; ++x) { + for (let y = 0; y < bNgram.length; ++y) { + if (aNgram[x] === bNgram[y]) { + hits += 1; + } + } + } + if (hits > 0) { + const union = aNgram.length + bNgram.length; + return (2.0 * hits) / union; + } + } + return 0; +}; + +/** resemblance + * is an alternative similarity rating; + * implements an 1-dim Ngram similarity check + * and it's much faster than similarity() + */ +const resemblance = (a, b, n) => { + if (a.length > n && b.length >= a.length) { + const aNgram = createNgram(a, n); + let hits = 0; + for (let i = 0; i < aNgram.length; ++i) { + if (b.includes(aNgram[i])) { + hits++; + } + } + if (hits > 0) { + // rate resemblance based on hits and length-similarity + return (hits / aNgram.length) * (a.length / b.length); + } + } + return 0; +} + + +/** is_exact_match + * + * check if a searching string -> query (string/latin in kb-format) + * matches exactly an item of the array of synonyms -> chkArr (array of utf-8/strings) + * + * @param query (string): searching string; string/latin in kb-format + * @param chkArr (array): array of synonyms; (array of utf-8/strings) + * @return (boolean): true|false + */ +function exact( query, chkArr ) { + found = false; + chkArr.forEach( w => { if (w == query) found = true }); + return found; +} + +function partial( query, chkArr ) { + found = false; + chkArr.forEach( w => { if (w.includes(query)) found = true }); + return found; +} + +module.exports = { + exact, + partial, + similarity, + resemblance +} |
