开发者

Fast Javascript String Replacement

Hey there geniuses of SO!

This is for an autocomplete plugin that needs to accept data as an array of arrays and convert it using a format string (or regex). The format string could be any format.

var dataArray = [ ["data1-1", "data1-2", "data1-3"], ["data2-1", "data2-2", "data2-3"],... ];
var format = "<li>{0} <br /> -- <small> {1}, {2}</small></li>";
// alternate formats could be: 
//  "<li>{0}</li>"
//  "<a href="{0}" title="{2}">{1} ({2})</a>"
// etc...

function fillAutocomplete(datum,format){
    // do some magic here...
    // return "<li>data1-1 <br /> -- <small> data1-2, data1-3</small></li>";
}

The following idea works..but i'd like to see if anything would be faster...

var datum = data[0],
    html="<li>\{0\} <br /> -- <small> \{1\}, \{2\}</small></li>";
for(var i=0,l=datum.length;i开发者_C百科<l;++i){
    var reg = new RegExp("\\{"+i+"\\}");
    html=html.replace(reg,datum[i]);
}

I'm open to new ideas on how to approach this problem.


Check out John Resig's "Search and Don't Replace" to see that you can pass a callback function to myString.replace(..).

var datum = data[0];
var html="<li>{0}<br /> -- <small>{1}, {2}</small></li>";
var pattern = /\{(\d+)\}/g;

html = html.replace(pattern,function(match, key, value){
    return datum[key];
});


While less elegant, this will be significantly faster:

html = "<li>" + datum[0] 
        + " <br /> -- <small> " 
        + datum[1] + ", " + datum[2] 
        + "</small></li>";

Your original approach creates a new regular expression for each iteration of the for loop which can be expensive. You could look into creating these expressions once and caching them perhaps but even then the overhead of executing the regular expression and replacing the format string will still be greater than a simple string concatenation.

Unfortunately elegance is often the first victim of optimization.


Depending on the number of replacements you need to make this could be faster

var datum = data[0],
    html="<li>{0} <br /> -- <small> {1}, {2}</small></li>";
for(var i=0,l=datum.length;i<l;++i){
    html=html.split("{" + i + "}").join(datum[i]);
}

there are some corner cases for when the {n} appears as the very first or last part of the string.


You can pass a function to replace as the second argument. Try this:

function fillAutocomplete(datum,format){
  return format.replace(/{([0-9]+)}/g, function(match) {
    return datum[match[1]];
  });
}


This should be the fastest if you still want to use HTML strings:

html = [
  "<li>", datum[0],
  "<br /> -- <small>",
  datum[1], ", ", datum[2],
  "</small></li>"
].join("");

Of course, it would be best if actually used the DOM.

html = document.createElement("li");
html.appendChild(document.createTextNode(datum[0]));
html.appendChild(document.createElement("br"));
html.appendChild(document.createTextNode(" -- "));
html.appendChild(document.createElement("small"))
  .appendChild(document.createTextNode(datum[1] + ", " + datum[2]));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜