How to better organize consecutive replace methods in JavaScript?

I have a sequence of replace methods, including regular expressions. They are all put together like this:

motivation = motivation.replace('death','life').replace('sad','happy').replace(/fu+ck/gi,'yay!').replace('darkness','light');

Is there a way to organize this to be more readable? Not having to repeat "replace" all the time would be a good start. I also have access to the Mootools library.

Answers


Here's the simplest thing I can think of: clever indentation.

motivation = motivation.replace('death','life')
   .replace('sad','happy')
   .replace(/fu+ck/gi,'yay!')
   .replace('darkness','light');

Another option is just to use something like Array.each (I think that's in Mootools):

Array.each([['death', 'life'],['sad', 'happy'],[/fu+ck/gi, 'yay!'],
            ['darkness', 'light']],
    function (pair) { motivation = motivation.replace(pair[0], pair[1]); });

This only really makes sense for very long lists of replacements.


You could add line-breaks.

motivation = motivation
             .replace('death','life')
             .replace('sad','happy')
             .replace(/fu+ck/gi,'yay!')
             .replace('darkness','light');

Other than that - unless you change the entire approach - no, I don't see how to improve it.

Changing the approach could mean something like this:

function replaceMany(s /*, [search, replace], ... */) {
  for (var i=1, l=arguments.length; i<l; i++) {
    s = s.replace(arguments[i][0], arguments[i][1]); 
  }
  return s;
}

Then you could call it as:

var motivation = replaceMany(
  motivation, 
  ['death','life'], ['sad','happy'], [/fu+ck/gi,'yay!'], ['darkness','light']
);

The advantage of wrapping it in a function is clearly that you can change what's being replaced without changing your source code. So unless you have a fixed, limited set of replacements that will never change, the latter approach is the better one.


I don't find the original unreadable, especially not if you add in some line breaks as suggested by the other answers. So I'd do exactly what Tomalak and Tikhon said.

But if you really want to avoid repeating .replace all the time you could create a function that takes in an array of find/replace text:

function replaceMany(str, replacements) {
   for (var i=0; i<replacements.length; i+++)
      str = str.replace(replacements[i][0], replacements[i][1]);
   return str;
}

motivation = replaceMany(motivation, [ ['death','life'],
                                       ['sad','happy'],
                                       [/fu+ck/gi,'yay!'],
                                       ['darkness','light'] ]);

Obviously I've chosen to make the replacements parameter an array where each element is a two-element array with the text to find (or regex) and the corresponding replacement text.

I don't really recommend messing with built-in object prototypes, but if you're someone who does then:

String.prototype.replaceMany = function(replacements) {
   var str = this;
   for (var i=0; i<replacements.length; i+++)
      str = str.replace(replacements[i][0], replacements[i][1]);
   return str;
}

motivations = motivations.replaceMany([/*array as above*/]);

Need Your Help

Custom user controls with the same method, calling them the same way

c# reflection user-controls

So I have made a bunch of user controls in my project which integrate into a system automatically that tracks certain things about them. But I'm unsure on how to do a certain part without it looking

Application in HTTP & HTTPS. But forms on HTTPs

forms http https

I have a requirement wherein the application must be on both http and https. While the end user must be able to traverse the application in http, all forms should transition to https post submissio...