Быстрая замена строки Javascript - PullRequest
3 голосов
/ 18 ноября 2009

Привет, гении ТАК!

Это для плагина автозаполнения, который должен принимать данные в виде массива массивов и преобразовывать их, используя строку формата (или регулярное выражение). Строка формата может быть любого формата.

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>";
}

Следующая идея работает ... но я бы хотел посмотреть, будет ли что-нибудь быстрее ...

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

Я открыт для новых идей о том, как подойти к этой проблеме.

Ответы [ 5 ]

11 голосов
/ 18 ноября 2009

Проверьте «Поиск и не заменяйте» Джона Ресига , чтобы увидеть, что вы можете передать функцию обратного вызова в 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];
});
1 голос
/ 18 ноября 2009

Будучи менее элегантным, это будет значительно быстрее:

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

Ваш оригинальный подход создает новое регулярное выражение для каждой итерации цикла for, что может быть дорогостоящим. Вы могли бы попытаться создать эти выражения один раз и, возможно, кэшировать их, но даже тогда издержки на выполнение регулярного выражения и замену строки формата все равно будут больше, чем простая конкатенация строк.

К сожалению, элегантность часто становится первой жертвой оптимизации.

0 голосов
/ 18 ноября 2009

Это должно быть быстрее, если вы все еще хотите использовать строки HTML:

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

Конечно, было бы лучше, если бы вы использовали 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 голосов
/ 18 ноября 2009

В зависимости от количества замен, которые вам нужно сделать, это может быть быстрее

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]);
}

В некоторых угловых случаях {n} отображается как самая первая или последняя часть строки.

0 голосов
/ 18 ноября 2009

Вы можете передать функцию для замены в качестве второго аргумента. Попробуйте это:

function fillAutocomplete(datum,format){
  return format.replace(/{([0-9]+)}/g, function(match) {
    return datum[match[1]];
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...