2009-03-29 5 views
1

J'ai une chaîne qui ressemble à quelque chose comme 'test: 1; bonjour: cinq; juste: 23'. Avec cette chaîne, je dois être en mesure de faire ce qui suit.javascript remplacer/ajouter

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

Le résultat final devrait être « test: 567, bonjour: cinq, il suffit de: 23, oui: 23 » (notez l'ordre exact des jetons est pas important).

Je me demandais si quelqu'un avait des idées intelligentes sur la façon de procéder. Je pensais remplacer une regex sur chacun des jetons à droite et si un remplacement ne se produisait pas parce qu'il n'y avait pas de correspondance, il suffit de l'ajouter. Mais peut-être qu'il y a un meilleur moyen.

Vive Anthony

Edit: Le côté droit devrait l'emporter sur la gauche. La gauche étant ce qui était à l'origine là et le côté droit étant le nouveau contenu. Une autre façon de voir, c'est que vous ne gardez les jetons sur la gauche que s'ils n'existent pas sur la droite et que vous gardez tous les jetons sur la droite.

@Ferdinand Merci pour la réponse. Le problème est l'efficacité avec laquelle la solution que vous avez proposée. Je pensais d'abord à des lignes similaires mais je l'ai escompté en raison de la complexité O (n * z) de la fusion (où n et z sont les jetons de nombre respectivement à gauche et à droite), sans parler de la division et de la jointure.

Par conséquent, pourquoi j'essayais de regarder le chemin d'une regex. Peut-être dans les coulisses, regex est tout aussi mauvais ou pire, mais ayant une regex qui supprime tout jeton de la chaîne de gauche qui existe sur la droite (O (n) pour le montant total de jeton sur la droite), puis ajoutez le 2 chaînes ensemble (c'est-à-dire test de la cuve = test1 + test2) semble plus efficace. grâce

+0

Recherche dans un Hashtable (JavaScript Object) est O (1), donc l'opération de fusion est linéaire, pas O (n²). Vous ne pouvez pas vraiment faire mieux que cela, même si regex avait le pouvoir de faire ce que vous vouliez (ce qui n'est pas possible). – bobince

+0

cool c'est quelque chose que je savais ... – vdhant

Répondre

0

Ce qui suit est ce que j'ai terminé thiking propos. Qu'est-ce que vous reconnaissez?

Merci 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

Eh bien, c'est essentiellement ce que j'ai suggéré, groupé dans un objet. Allez-y et ne pensez pas trop à l'optimisation à moins qu'elle ne fonctionne vraiment mal, ce dont je doute. –

+0

J'ai fait quelques recherches et l'approche regex à laquelle je pensais, semble être plus lente. Je sais que c'est enveloppé dans un objet mais c'est ce que je regardais à l'origine mais je voulais voir s'il y avait une approche alternative. J'ai découvert qu'il n'y avait pas. Merci à la fin.seenext – vdhant

+0

Enfin, je pense que la différence principale avec ce que j'ai mis ensemble est du côté de la fusion. Je pense que pour les grands ensembles de jetons car je n'utilise pas la boucle imbriquée pour rechercher des correspondances ou une autre boucle pour rejoindre. Je pense que la performance dans ce qui précède serait mieux. Laissez-moi savoir ce que vous pensez. – vdhant

6

J'utiliser join() et split() pour créer des fonctions utilitaires pour compresser et décompresser vos données jeton à un objet:

// 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(';'); 
} 

En utilisant ces derniers, la fusion est facile:

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

L'utilitaire les fonctions sont également utiles si vous voulez extraire certaines clés (par exemple, "test") et/ou vérifier leur existence:

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

Taper presque le même et en vérifiant le code dans la console FireBug :) –

+0

Voir mon edit dans le dessus – vdhant

0

je suis quelques années en retard, mais je pense que c'est ce que vous cherchez:

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