patternjavascriptMinor
Substituting Hebrew letter variants
Viewed 0 times
lettervariantshebrewsubstituting
Problem
I have two functions that replace letters. In one function, I'm replacing a regular Hebrew letter with its final form, and the other function undoes this operation. (Consider it like lowercase/uppercase, except only a few letters have both forms.)
I created an object where the keys are the regular forms and the values are the final forms. In each function, I iterate over the object and run a regex - in one function it's
Would it be worth it / even possible to abstract this
(
I created an object where the keys are the regular forms and the values are the final forms. In each function, I iterate over the object and run a regex - in one function it's
map[i] -> i; the other is i -> map[i].Would it be worth it / even possible to abstract this
for loop into a function?var map = {
כ: 'ך',
מ: 'ם',
נ: 'ן',
פ: 'ף',
צ: 'ץ'
};
exports.toFinal = function(text) {
for (var i in map) {
text = text.replace(new RegExp(i,'g'), map[i]);
}
return text;
}
exports.toRegular = function(text) {
for (var i in map) {
text = text.replace(new RegExp(map[i],'g'), i);
}
return text;
}(
exports is Node.js's exports object, and the code is implicitly running in a closure.)Solution
I would opt for another implementation.
You iterate over your map and for each value, you replace a character in the source string. So for n characters in your map, you run n replacement operations for a length of m. Given, that n = m, that takes n^2 steps.
I would make two maps; one for each direction:
(for simplicity reasons, I chose latin letters)
If I need to know, whether there is a translation, I could do a simple operation
A translation - independent of the direction - could be defined as:
Is a letter in the map, translate it, else return the original letter.
To specify the direction, you could define a closure, passing in the appropriate map:
If you want to translate more than one character, you have to split the string and translate each character. After that join the result:
Which results in two functions:
The resulting code looks like this:
You iterate over your map and for each value, you replace a character in the source string. So for n characters in your map, you run n replacement operations for a length of m. Given, that n = m, that takes n^2 steps.
I would make two maps; one for each direction:
(for simplicity reasons, I chose latin letters)
var form1 = {
'a':'A',
'b':'B'
};
var form2 = {
'A':'a',
'B':'b'
};If I need to know, whether there is a translation, I could do a simple operation
form1['a'] or form1['x'].A translation - independent of the direction - could be defined as:
function translate(x){
return (map[x])?map[x]:x;
}Is a letter in the map, translate it, else return the original letter.
To specify the direction, you could define a closure, passing in the appropriate map:
function makeTranslation(map){
return function translate(x){
return (map[x])?map[x]:x;
}
}If you want to translate more than one character, you have to split the string and translate each character. After that join the result:
function translate(expression, direction){
return expression.split("").map(direction).join("");
}Which results in two functions:
function toFinal(expression){
return translate(expression, makeTranslation(form1));
}
function toRegular(expression){
return translate(expression, makeTranslation(form2));
}The resulting code looks like this:
var form1 = {
'a':'A',
'b':'B'
};
var form2 = {
'A':'a',
'B':'b'
};
function makeTranslation(map){
return function translate(x){
return (map[x])?map[x]:x;
}
}
function translate(expression, direction){
return expression.split("").map(direction).join("");
}
function toFinal(expression){
return translate(expression, makeTranslation(form1));
}
function toRegular(expression){
return translate(expression, makeTranslation(form2));
}
console.log(toRegular(toFinal("aabbcbb"))==='aabbcbb');
console.log(toFinal(toRegular("AABBcBB"))==='AABBcBB');
Code Snippets
var form1 = {
'a':'A',
'b':'B'
};
var form2 = {
'A':'a',
'B':'b'
};function translate(x){
return (map[x])?map[x]:x;
}function makeTranslation(map){
return function translate(x){
return (map[x])?map[x]:x;
}
}function translate(expression, direction){
return expression.split("").map(direction).join("");
}function toFinal(expression){
return translate(expression, makeTranslation(form1));
}
function toRegular(expression){
return translate(expression, makeTranslation(form2));
}Context
StackExchange Code Review Q#70606, answer score: 3
Revisions (0)
No revisions yet.