Question

I have a string that looks something like the following 'test:1;hello:five;just:23'. With this string I need to be able to do the following.

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

The end result should be 'test:567;hello:five;just:23;yes:23' (note the exact order of the tokens is not that important).

Just wondering if anyone has any smart ideas of how to go about this. I was thinking a regex replace on each of the tokens on right and if a replace didn't occur because there was not match just append it. But maybe there is better way.

Cheers Anthony

Edit: The right side should override the left. The left being what was originally there and the right side being the new content. Another way of looking at it, is that you only keep the tokens on the left if they don't exist on the right and you keep all the tokens on the right.

@Ferdinand Thanks for the reply. The problem is the efficiency with which the solution you proposed. I was initially thinking down similar lines but discounted it due to the O(n*z) complexity of the merge (where n and z is the number tokens on the left and right respectively) let alone the splitting and joining.

Hence why I was trying to look down the path of a regex. Maybe behind the scenes, regex is just as bad or worse, but having a regex which removes any token from the left string that exists on the right (O(n) for the total amount of token on the right) and then just add the 2 string together (i.e. vat test = test1 + test2) seems more efficient. thanks

Was it helpful?

Solution 2

The following is what I ended thiking about. What do you guys recon?

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

OTHER TIPS

I would use join() and split() to create some utility functions to pack and unpack your token data to an object:

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

Using these, merging is easy:

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

The utility functions are also useful if you want to extract some keys (say,"test") and/or check for existence:

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

i am a few years late, but i think this is what you are looking for:

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top