7
\$\begingroup\$

I have some code to translate some color names, and this is what I did, quick and dirty. But I'm guessing there might be some function to replace arrays with arrays maybe, like in PHP, where you can have str_replace($array_of_colors, $replace_array_of_colors, $colors);.

var color = colors[c].replace(/sort/i, "Black");
color = color.replace(/brun/i, "Brown");
color = color.replace(/hvit/i, "White");
color = color.replace(/oransje/i, "Orange");
color = color.replace(/gul/i, "Yellow");
color = color.replace(/beige/i, "Beige");
color = color.replace(/Mørk/i, "Dark");
color = color.replace(/Rosa/i, "Pink");
color = color.replace(/rød/i, "Red");
color = color.replace(/Blå/i, "Blue");
color = color.replace(/grå/i, "Gray");
color = color.replace(/Lys/i, "Light");
color = color.replace(/lilla/i, "Purple");
\$\endgroup\$

2 Answers 2

10
\$\begingroup\$

You're mixing up data and logic. Separate your replaces into an associative array and iterate over that instead: (My JS is extremely bad, so this will be more pseudocode-ish)

var associations;
associations['/brun/i'] = "Brown";
associations['/sort/i'] = "Black";
//add all the other associations and then

associations.forEach(runReplace);

function runReplace(value, regex, array) {
   color.replace(regex, value);
}

Additionally I suggest you (just like me here) use the Array.prototype.forEach() when iterating over your colors

\$\endgroup\$
10
\$\begingroup\$

Maintenance is key. Anything that might change in the future is the mapping of the keys to the translated color names. So let´s keep that part as simple as possible with a simple key/value mapping:

var colors = {
  sort: 'Black',
  brun: 'Brown',
  hvit: 'White'
};

Instead of checking for each key individually, let´s create one regular expression that includes every key. Object.keys() returns the keys of an object as an array. Array.prototype.join(val) concatenates every element of an array with val. The pipe | signals an or in a regular expression. Do not forget to set the flags g for multiple occurences of the same key in the text as well as the i to ignore case sensitivity.

var regExp = new RegExp("(" + Object.keys(colors).join('|') + ')', 'gi');

The second parameter of String.prototype.replace() must not be a string, but can also be a function to replace strings dynamically. The first parameter of dynamicReplace is the part of the regex that actually matched. The second parameter key is the part that matched the string we put in parentheses ( ) within our regular expression. In this example match and key result in the same string, but this might not be the case for more complex regular expressions. dynamicReplace uses the mapping as a lookup table to return the translated color.

var text = 'My sort cat is brun!';
console.log(text.replace(regExp, function dynamicReplace(match, key) {
  return colors[key];
}));

// => My Black cat is Brown! 
\$\endgroup\$
2
  • \$\begingroup\$ I would add that subjecting the result of a substitution to further substitution can be a source of bugs — it just happens not to be a problem in this case. Note that in the general case, you have to watch out for special characters when constructing the regex. \$\endgroup\$ Commented Nov 17, 2014 at 23:57
  • \$\begingroup\$ @200_success: I do not understand your first statement tbh. var colors = { a: 'b', b: 'c' } and var text = 'ab' still result in text === 'bc'. So further substitutions are not applied to the result of previous one. Or what do you mean? \$\endgroup\$
    – Amberlamps
    Commented Nov 18, 2014 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.