2009-03-29 14 views
1

Ich habe eine Zeichenfolge, die in etwa so aussieht wie der folgende 'test: 1; hallo: fünf; nur: 23'. Mit dieser Zeichenfolge muss ich Folgendes tun können.Javascript Token ersetzen/anhängen

.... 
var test = MergeTokens('test:1;hello:five;just:23', 'yes:23;test:567'); 
... 

Das Endergebnis sollte 'Test: 567; hallo: fünf, nur: 23, ja: 23' sein (beachten Sie die genaue Reihenfolge der Token ist nicht so wichtig).

Ich frage mich nur, ob jemand irgendwelche kluge Ideen hat, wie man das macht. Ich dachte, ein Regex würde auf jedem der Token auf der rechten Seite ersetzen und wenn ein Ersetzen nicht stattfinden würde, weil es keine Übereinstimmung gab, einfach anhängen. Aber vielleicht gibt es einen besseren Weg.

Prost Anthony

Edit: Die rechte Seite sollte die linke außer Kraft setzen. Das Linke ist das, was ursprünglich dort war, und die rechte Seite ist der neue Inhalt. Eine andere Betrachtungsweise ist, dass Sie die Token nur links behalten, wenn sie nicht rechts vorhanden sind und Sie alle Token auf der rechten Seite behalten.

@ Ferdinand Danke für die Antwort. Das Problem ist die Effizienz, mit der die Lösung, die Sie vorgeschlagen haben. Ich dachte zuerst über ähnliche Zeilen nach, aber diskontierte sie aufgrund der O (n * z) -Komplexität der Zusammenführung (wobei n und z jeweils die Zahlentoken links und rechts sind), geschweige denn das Teilen und Verbinden.

Deshalb, warum ich versuchte, den Weg einer Regex hinunter zu schauen. Vielleicht ist regex hinter den Kulissen genauso schlimm oder schlechter, aber mit einer Regex, die ein Token aus der linken Zeichenfolge entfernt, die auf der rechten Seite (O (n) für die Gesamtmenge von Token auf der rechten Seite) und fügen Sie einfach die 2 string zusammen (dh vat test = test1 + test2) scheint effizienter.

dank
+0

Lookup in einem Hash-Tabelle (JavaScript Object) O (1), so ist die Zusammenführungsoperation linear, nicht O (n²). Sie können nicht wirklich besser als das tun, selbst wenn Regex die Macht hatte, zu tun, was Sie wollten (was es nicht kann). – bobince

+0

cool das ist etwas, was ich wusste ... – vdhant

Antwort

0

Das folgende ist, worüber ich endete. Was recherchiert ihr?

Dank Anthony

function Tokenizer(input, tokenSpacer, tokenValueSpacer) { 
    this.Tokenizer = {}; 
    this.TokenSpacer = tokenSpacer; 
    this.TokenValueSpacer = tokenValueSpacer; 
    if (input) { 
     var TokenizerParts = input.split(this.TokenSpacer); 
     var i, nv; 
     for (i = 0; i < TokenizerParts.length; i++) { 
      nv = TokenizerParts[i].split(this.TokenValueSpacer); 
      this.Tokenizer[nv[0]] = nv[1]; 
     } 
    } 
} 

Tokenizer.prototype.add = function(name, value) { 
    if (arguments.length == 1 && arguments[0].constructor == Object) { 
     this.addMany(arguments[0]); 
     return; 
    } 
    this.Tokenizer[name] = value; 
} 

Tokenizer.prototype.addMany = function(newValues) { 
    for (nv in newValues) { 
     this.Tokenizer[nv] = newValues[nv]; 
    } 
} 

Tokenizer.prototype.remove = function(name) { 
    if (arguments.length == 1 && arguments[0].constructor == Array) { 
     this.removeMany(arguments[0]); 
     return; 
    } 
    delete this.Tokenizer[name]; 
} 

Tokenizer.prototype.removeMany = function(deleteNames) { 
    var i; 
    for (i = 0; i < deleteNames.length; i++) { 
     delete this.Tokenizer[deleteNames[i]]; 
    } 
} 

Tokenizer.prototype.MergeTokenizers = function(newTokenizer) { 
    this.addMany(newTokenizer.Tokenizer); 
} 

Tokenizer.prototype.getTokenString = function() { 
    var nv, q = []; 
    for (nv in this.Tokenizer) { 
     q[q.length] = nv + this.TokenValueSpacer + this.Tokenizer[nv]; 
    } 
    return q.join(this.TokenSpacer); 
} 

Tokenizer.prototype.toString = Tokenizer.prototype.getTokenString; 
+0

Nun, es ist im Wesentlichen, was ich vorgeschlagen, in einem Objekt gruppiert. Gehen Sie mit und denken Sie nicht zu viel über Optimierung nach, es sei denn, es funktioniert wirklich schlecht, was ich bezweifle. –

+0

Ich habe etwas recherchiert und der Regex-Ansatz, über den ich nachgedacht habe, sieht aus, als würde es langsamer funktionieren. Ich weiß, dass dies in ein Objekt eingewickelt ist, aber das ist es, was ich ursprünglich gesehen habe, aber ich wollte sehen, ob es einen alternativen Ansatz gibt. Ich fand heraus, dass es nicht war. Thanks though.seenext – vdhant

+0

Schließlich denke ich, der Hauptunterschied mit dem, was ich hier zusammengefügt habe, ist auf der merging Seite. Ich denke das für große Token-Sets, weil ich die verschachtelte Schleife nicht verwende, um nach Übereinstimmungen oder einer anderen Schleife zu suchen. Ich würde denken, dass die Leistung in den oben genannten besser wäre. Lass mich wissen was du denkst. – vdhant

6

ich join() und split() verwenden würde einige Utility-Funktionen erstellen Sie Ihre Token-Daten zu einem Objekt zu packen und entpacken:

// Unpacks a token string into an object. 
function splitTokens(str) { 
    var data = {}, pairs = str.split(';'); 
    for (var i = 0; i < pairs.length; ++i) { 
     var pair = pairs[i].split(':'); 
     data[pair[0]] = pair[1]; 
    } 
    return data; 
} 

// Packs an object into a token string. 
function joinTokens(data) { 
    var pairs = []; 
    for (var key in data) { 
     pairs.push(key + ":" + data[key]); 
    } 
    return pairs.join(';'); 
} 

diese verwenden, Verschmelzung ist einfach:

// Merges all token strings (supports a variable number of arguments). 
function mergeTokens() { 
    var data = {}; 
    for (var i = 0; i < arguments.length; ++i) { 
     var d = splitTokens(arguments[i]); 
     for (var key in d) { 
      data[key] = d[key]; 
     } 
    } 
    return joinTokens(data); 
} 

Das Dienstprogramm Funktionen sind auch nützlich, wenn Sie einige Schlüssel (zB "test") extrahieren und/oder auf Existenz prüfen wollen:

var data = splitTokens(str); 
if (data["test"] === undefined) { 
    // Does not exist 
} else { 
    alert("Value of 'test': " + data["test"]); 
} 
+0

War fast das Gleiche und Überprüfung des Codes in FireBug-Konsole :) –

+0

Siehe meine Bearbeitung in der obigen – vdhant

0

ich bin ein paar Jahre zu spät, aber ich denke, das ist das, was Sie suchen,:

function MergeTokens(input, replace){ 
var replaceTokens = replace.split(";"); 
for(i=0; i<replaceTokens.length; i++){ 
    var pair = replaceTokens[i].split(":"); 
    var result = input; 
    regString = "\\b" + pair[0] + ":[\\w]*\\b"; 
    var reg = new RegExp(regString); 
    if(reg.test(result)){ 
    result = result.replace(reg, replaceTokens[i]); 
    } 
    else{ 
    result = result + replaceTokens[i]; 
    } 
} 
return result; 
} 
Verwandte Themen