Все, что можно написать о Soundex, уже давно написано, а вот реализации для русского языка на JavaScript не видел.
Решил написать, на мой взгляд, код вышел чистым, а вот впечатление от использования не очень, слабоват алгоритм.
/*******************************************************************************
* @Name : "Soundex.js" // Имя
* #Guid : {0C9C1C6F-3C9F-4223-A37E-072E97EBAC44} // GUID
* @Create : 11.01.2015/04:58:32 // Дата создания
* GPL applies. No warranties XGuest
*******************************************************************************/
'use strict';init();
var console = require('console').console; //
function sndx(a) {
var b = {
"en" : [/[^A-Z]/ig, /[BFPV]/ig, /[CGJKQSXZ]/ig, /[DT]/ig, /[L]/ig, /[MN]/ig, /[R]/ig, /[HW]/ig, /[AEIOUY]/ig],
"ru" : [/[^А-Я]/ig, /[БВПФ]/ig, /[ГЗКСХЦ]/ig, /[ДТ]/ig, /[Л]/ig, /[МН]/ig, /[Р]/ig, /[ЖЙЧШЩЬЪ]/ig, /[АЕЁИОУЫЭЯЮ]/ig],
"all" : [/[^A-ZА-Я]/ig, // 0 - Алфавит
/[BFPVБВПФ]/ig, // 1 +
/[CGJKQSXZГЗКСХЦ]/ig, // 2 ¦
/[DTДТ]/ig, // 3 ¦
/[LЛ]/ig, // 4 + Кодируемые согласные
/[MNМН]/ig, // 5 ¦
/[RР]/ig, // 6 +
/[HWЖЙЧШЩЬЪ]/ig, // 7 - Не кодируемые согласные
/[AEIOUYАЕЁИОУЫЭЯЮ]/ig]}[a]; // 8 - Гласные
return function(a) {
return (
a.charAt(0)+( // Сохраняем первый символ
function(a){for(var c=7;--c;){a=a.replace(b[c],c);}return a;} // Кодируем согласные
(a.replace(b[0],""). // Удаляем не алфавитные
replace(b[7],function(a,b,c){return!c||b;})). // Удаляем не кодируемые
replace(/(.)1*/gi,"$1"). // Удаляем повтор кода
slice(1)+"000"). //
replace(b[8],"")). // Удаляем гласные
slice(0,4).toUpperCase(); //
};
}
Пример использования
function test(a) {
console.time("Test Soundex");
var b = {
"Ashcraft": ["A261", "=> A261 != A226 - 'S' и 'C' объеденяются, так как 'h' удаляется"],
"Lloyd": ["L300", "=> L300 != L430 - 'L' и 'l' объеденяются, имеют одинаковый код 4"],
"Tymczak": ["T522", "=> T522 != T520 - 'Z' и 'K' не объеденяются, между ними гласная"],
"Arnold": ["A654", "Пример на английском языке"],
"Арнольд": ["А654", "Пример на русском языке"]
};
var soundex=sndx("all"); // Выбор таблицы кодов
var c = Array(8).join(" ");
function tst(a) {
if(a) {
d = soundex(a);
console.log("{0}:{1}-{2} {3} {4}", (a + c).slice(0, c.length), b[a][0], d, d === b[a][0],b[a][1]);}
else {for(e in b) b.hasOwnProperty(e) && tst(e);}
}
tst(a);
console.timeEnd("Test Soundex");
}
test();