2009-03-29 5 views
1

を追加します。この文字列で私は以下を行うことができる必要があります。Javascriptがトークン交換する/私は、次のようになります文字列を持っている

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

最終結果は「テスト:567;こんにちは:5;ちょうど:23;はい:23」でなければなりません(トークンの正確な順序は重要ではないことに注意)。誰もがこのについて移動する方法のいずれかのスマートなアイデアを持っている場合

ただ不思議。私は正規表現が右の各トークンに置き換わると思っていましたが、置き換えが起こらなかったのは、それに単にマッチしなかったためです。しかし、おそらくもっと良い方法があります。

乾杯 アンソニー

編集:右側が左をオーバーライドする必要があります。左は最初はそこにあり、右は新しいコンテンツです。それを見るもう1つの方法は、右に存在しない場合にのみトークンを左に保持し、右にすべてのトークンを保持することです。

@Ferdinand お返事ありがとうございます。問題は、提案したソリューションの効率です。私は当初同様の行を考えていましたが、分割と結合はもちろんのこと、マージのO(n * z)複雑さ(nとzはそれぞれ左と右の数字トークンです)のためにそれを割り引いていました。

したがって、なぜ私は正規表現の道を探すためにしようとしていました。たぶん背後、正規表現は、同様に不良または悪化であるが、正規表現を有する右側(右側のトークンの合計量のためにO(N))に存在する左列から任意のトークンを除去した後、ちょうど追加います2つの文字列(すなわち、vat test = test1 + test2)の方が効率的です。おかげ

+0

検索ハッシュテーブル(JavaScriptオブジェクト)でO(1であります)、マージ操作はO(n²)ではなく線形です。正規表現があなたが望むことをする力を持っていたとしても(それはできない)、あなたはそれよりもうまくいくわけではありません。私が知っていた何か... – bobince

+0

クール:) – vdhant

答えて

0

次は私がチンキングを終えたものです。あなたは何を偵察していますか?

おかげ アンソニー

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

以上で私の編集を参照してください。それと一緒に行くと、それは本当にひどく実行しない限り、最適化についてあまり考えていない、私は疑う。 –

+0

私はいくつかの研究を行い、私が考えていた正規表現のアプローチは、より遅く実行されるように見えます。私はこれがオブジェクトに包まれていることを知っていますが、これは私が元々見ていたものですが、代替のアプローチがあるかどうかを見たいと思っていました。私は見つけられなかった。ありがとうthough.seenext – vdhant

+0

最後に、ここで私がまとめたものとの主な違いは、合併側にあると思います。大きなトークンセットの場合は、ネストループを使用して一致を検索したり、別のループを使用して結合したりしないためです。私は上記のパフォーマンスが良いと思うでしょう。どう考えているか教えてください。 – vdhant

6

私はパックしたオブジェクトに、あなたのトークンデータを解凍するために、いくつかのユーティリティ関数を作成するためにjoin()split()を使用します。これらを使用して

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

、マージは簡単です:

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

ユーティリティあなたには、いくつかのキー(たとえば、「テスト」)を抽出し、および/または存在をチェックしたい場合は機能も有用である:

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

はほぼ同じと入力し、Firebugのコンソールでコードをチェックしていたある –

+0

まあそれがオブジェクトにグループ化された、私が提案し何本質的だ – vdhant

0

私は後半の数年間が、私は、これはあなたが探しているものだと思う:

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; 
} 
関連する問題