talisman
Version:
Straightforward fuzzy matching, information retrieval and NLP building blocks for JavaScript.
128 lines (101 loc) • 2.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = cologne;
var _helpers = require('../../helpers');
var _deburr = require('lodash/deburr');
var _deburr2 = _interopRequireDefault(_deburr);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Maps.
*/
/**
* Talisman phonetics/german/cologne
* ==================================
*
* The cologne algorithm.
*
* [Reference]:
* https://en.wikipedia.org/wiki/Cologne_phonetics
*
* [Article]:
* Hans Joachim Postel: Die Kölner Phonetik. Ein Verfahren zur Identifizierung
* von Personennamen auf der Grundlage der Gestaltanalyse.
* in: IBM-Nachrichten, 19. Jahrgang, 1969, S. 925-931.
*/
var CODES = {
H: null,
A: 0,
E: 0,
I: 0,
O: 0,
U: 0,
J: 0,
Y: 0,
B: 1,
P: 1,
F: 3,
V: 3,
W: 3,
G: 4,
K: 4,
Q: 4,
L: 5,
M: 6,
N: 6,
R: 7,
S: 8,
Z: 8
};
var DT = new Set(['C', 'S', 'Z']),
CFollowing1 = new Set(['A', 'H', 'K', 'L', 'O', 'Q', 'R', 'U', 'X']),
CFollowing2 = new Set(['A', 'H', 'K', 'O', 'Q', 'U', 'X']),
CPrevious = new Set(['S', 'Z']),
X = new Set(['C', 'Q', 'K']);
/**
* Helpers.
*/
function germanicSubstitutions(name) {
return name.replace(/Ä/g, 'A').replace(/Ö/g, 'O').replace(/Ü/g, 'U').replace(/ß/g, 'SS').replace(/PH/g, 'F');
}
/**
* Function taking a single name and computing its cologne code.
*
* @param {string} name - The name to process.
* @return {string} - The cologne code.
*
* @throws {Error} The function expects the name to be a string.
*/
function cologne(name) {
if (typeof name !== 'string') throw Error('talisman/phonetics/german/cologne: the given name is not a string.');
// Preparing the name
name = (0, _deburr2.default)(germanicSubstitutions(name.toUpperCase())).replace(/[^A-Z]/g, '');
// Processing the letters of the name
var code = [];
for (var i = 0, l = name.length; i < l; i++) {
var letter = name[i],
possibleCode = CODES[letter];
if (possibleCode !== undefined) code.push(possibleCode);
// Handling D/T
else if (letter === 'D' || letter === 'T') code.push(DT.has(name[i + 1]) ? 8 : 2);
// Handling C
else if (letter === 'C') {
var previous = name[i - 1],
following = name[i + 1];
if (!previous && CFollowing1.has(following) || CFollowing2.has(following) && !CPrevious.has(previous)) {
code.push(4);
} else {
code.push(8);
}
}
// Handling X
else if (letter === 'X') code.push(X.has(name[i - 1]) ? 8 : 48);
}
// Squeezing and dropping 0 if not first letter
code = (0, _helpers.squeeze)(code).filter(function (letter, i) {
return !i || letter;
});
return code.join('');
}
module.exports = exports['default'];