2009-11-17 4 views
3

Hey là des génies de SO!Remplacement rapide de chaîne de Javascript

Ceci est pour un plugin de saisie semi-automatique qui doit accepter des données sous la forme d'un tableau de tableaux et le convertir en utilisant une chaîne de format (ou regex). La chaîne de format pourrait être n'importe quel 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>"; 
} 

L'idée suivante works..but je voudrais voir si quelque chose serait plus rapide ...

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

Je suis ouvert à de nouvelles idées sur la façon d'aborder ce problème.

Répondre

11

Vérifiez le "Search and Don't Replace" de John Resig pour voir que vous pouvez passer une fonction de rappel à 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]; 
});
+0

Ah, je me souviens d'avoir lu ça il y a un moment. Je vais l'essayer plus tard. Merci beaucoup! –

+0

+1. Merci pour cela, je n'avais aucune idée que vous pouviez passer une fonction pour analyser la correspondance actuelle pendant la boucle de remplacement. – Matt

+0

fonctionne à merveille! Merci! Je me demande si le modèle de John Resig sera plus rapide. hm. Je reviendrai à vous tous sur celui-là demain. –

1

Bien que moins élégante, ce sera nettement plus rapide:

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

Votre approche originale crée une nouvelle expression régulière pour chaque itération de la boucle for qui peut être coûteux. Vous pourriez envisager de créer ces expressions une seule fois et de les mettre en cache peut-être, mais même dans ce cas, le temps d'exécution de l'expression régulière et le remplacement de la chaîne de format seront toujours supérieurs à une simple concaténation de chaîne.

Malheureusement, l'élégance est souvent la première victime de l'optimisation.

+0

C'était ainsi que c'était à l'origine. Je vais mettre à jour ma question pour le rendre plus clair. J'ai besoin que la chaîne de format soit dynamique pour chaque ensemble de données. –

0

Vous pouvez passer une fonction à remplacer comme deuxième argument. Essayez ceci:

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

En fonction du nombre de remplacements que vous devez faire cela pourrait être plus rapide

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

il y a quelques cas de coin pour quand l'{n} apparaît comme la partie première ou la dernière des chaîne.

0

Cela devrait être le plus rapide si vous voulez continuer à utiliser les chaînes HTML:

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

Bien sûr, il serait préférable si effectivement utilisé les 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

Il pourrait être philosophiquement "meilleur" d'utiliser le DOM, mais il sera pragmatiquement plus lent, beaucoup plus lent ... – JasonWyatt

+0

Jason, il est plus lent d'utiliser la chaîne car elle doit être convertie en DOM de toute façon. –