wikimedica-disease-search/app/src/data/fuzzy.js

78 lines
1.7 KiB
JavaScript
Raw Normal View History

import * as diacritics from 'diacritics';
/**
* Motifs de désuffixation des mots français.
*/
const stemPatterns = [
[/aux$/, 'al'],
[/(.)s$/, '$1'],
[/(.)e$/, '$1'],
];
/**
* Motif de séparation des mots.
*/
const splitPattern = /[\s-]+/g;
/**
* Désuffixe un mot français.
*
* @param word Mot originel.
* @return Mot désuffixé.
*/
const stemWord = word =>
{
let result = word;
for (let [pattern, replacement] of stemPatterns)
{
result = result.replace(pattern, replacement);
}
return result;
};
/**
* Met le nom dun terme sous forme normalisée pour la recherche approximative.
*
* Dans la forme normalisée, tous les accents sont ôtés, la casse est réduite
* en minuscules et les mots sont désuffixés.
*
* @param name Nom à normaliser.
* @return Liste des mots du nom de terme normalisé.
*/
const normalizeName = name =>
diacritics.remove(name.toLowerCase())
.split(splitPattern)
.map(stemWord);
/**
* Filtre une liste de termes pour ne garder que ceux qui sont similaires à une
* saisie.
*
* @param search Contenu de la saisie.
* @param term Terme à vérifier.
* @return Ensemble des termes sélectionnés.
*/
export const filterTerms = (search, terms) =>
{
// Normalisation des mots recherchés
const needle = normalizeName(search);
console.log(needle);
return terms.filter(term =>
{
// Normalisation du nom et des alias du terme
const haystack = [term.name].concat(term.alias)
.map(normalizeName)
.reduce((prev, next) => prev.concat(next), []);
return needle.every(item =>
haystack.some(word =>
word.startsWith(item)
)
);
});
};