return FALSE; $r = well_tag_thread__update(array('id' => $id), $update); return $r; } function well_tag_thread_find($tagid, $page, $pagesize) { $arr = well_tag_thread__find(array('tagid' => $tagid), array('id' => -1), $page, $pagesize); return $arr; } function well_tag_thread_find_by_tid($tid, $page, $pagesize) { $arr = well_tag_thread__find(array('tid' => $tid), array(), $page, $pagesize); return $arr; } ?>regex - Merging two strings of key=value pairs in JavaScript - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

regex - Merging two strings of key=value pairs in JavaScript - Stack Overflow

programmeradmin1浏览0评论

I'm trying to e up with an efficient way to overwrite 2 strings that look like this:

str1 = "width=800,height=600,resizable=no,titlebar=no";
str2 = "width=100,height=100";

In the above example, str2 should overwrite str1 to produce str3:

str3 = "width=100,height=100,resizable=no,titlebar=no";

In my tests, I turned str2 into an array and tested each key against a match in str1.

Can anyone think of a more efficient way to write this:

str1 = "width=800,height=600,resizable=no,titlebar=no";
str2 = "width=100,height=100";
sArray = str2.split(",");

for( var i = 0; i < sArray.length; i++ ) {
    var key = sArray[i].match(/(\w+)=/gi).toString().replace("=", ""),
        in_str1 = str1.search(key),
        replace_pattern = new RegExp(key+"=(\\w+)", "gi");

    if(in_str1 !== -1){                 
        str1 = str1.replace(replace_pattern, sArray[i]);
    } else {
        str1 = str1 + "," + sArray[i];
    }
}

I'm trying to e up with an efficient way to overwrite 2 strings that look like this:

str1 = "width=800,height=600,resizable=no,titlebar=no";
str2 = "width=100,height=100";

In the above example, str2 should overwrite str1 to produce str3:

str3 = "width=100,height=100,resizable=no,titlebar=no";

In my tests, I turned str2 into an array and tested each key against a match in str1.

Can anyone think of a more efficient way to write this:

str1 = "width=800,height=600,resizable=no,titlebar=no";
str2 = "width=100,height=100";
sArray = str2.split(",");

for( var i = 0; i < sArray.length; i++ ) {
    var key = sArray[i].match(/(\w+)=/gi).toString().replace("=", ""),
        in_str1 = str1.search(key),
        replace_pattern = new RegExp(key+"=(\\w+)", "gi");

    if(in_str1 !== -1){                 
        str1 = str1.replace(replace_pattern, sArray[i]);
    } else {
        str1 = str1 + "," + sArray[i];
    }
}
Share Improve this question asked Aug 4, 2010 at 17:47 AndresAndres 5,2286 gold badges32 silver badges35 bronze badges 1
  • Thank you all for the help. This is what I did with the snippet: andresvidal./labs/popup.html – Andres Commented Aug 6, 2010 at 13:16
Add a ment  | 

3 Answers 3

Reset to default 7

Here's a pretty terse regex-based solution:

str3 = str2 + "," + str1;

while ((temp = str3.replace(/\b([a-z]+)(=.*)\b\1=[^,]*,?/, "$1$2")) != str3) {
    str3 = temp;
}

It works by prepending the overriding string to the overridable string, then repeatedly stripping out duplicates that occur later in the joined string until there aren't any.

A little more care will be needed if either string could be empty, or if any kind of escaping is permitted, or if the keys can be named other than with letters only.

Didn't try running it, but this ought to work, created a utility function parseParamString that accepts a string of that format, and optionally an object to add the key-value pairs to.

function parseParamString(str, obj) {
    var pairs = str.split(","),
        i = 0, l = pairs.length,
        pair;
    obj || (obj = {});
    for (; l > i; ++i) {
        pair = pairs[i].split("=", 2);
        obj[pair[0]] = pair[1];
    }
    return obj;
}

function buildParamString(obj) {
    var pairs = [], i;
    for (i in obj) {
        if (obj.hasOwnProperty(i)) {
            pairs.push(i + "=" + obj[i]);
        }
    }
    return pairs.join(",");
}

var str1 = "width=800,height=600,resizable=no,titlebar=no",
    str2 = "width=100,height=100";

var resultObj = parseParamString(str2, parseParamString(str1));

var resultSTr = buildParamString(resultObj);

Edit: forgot about turning the object back into a string.

I came up with the following, but I'm not sure if it'll be faster than your method since there's a few more steps involved. Also it's a bit longer...

var toObj = function (str) {
   var arr = str.split(","), obj = {};
   for (var i = 0; i < arr.length; i++) {
      var keyval = arr[i].split("=", 2);
      obj[keyval[0]] = keyval[1];
   }
   return obj;
};

var objToString = function (obj) {
   var stringBuilder = [];
   for (var k in obj) {
      stringBuilder.push(k+"="+obj[k]);
   }
   return stringBuilder.join(",");
};

var merge  = function (obj1, obj2) { // merge obj1 into obj2.. obj2 will be modified.
   for (var k in obj1) {
      obj2[k] = obj2[k] || obj1[k];
   }
   return obj2;
};

var newStr = objToString(merge(toObj(str1), toObj(str2));

Benchmarking

I was bored, so I decided to do a quick benchmark of these 3 different solutions offered.

Benchmarking function/test:

function benchmark(name, fn, n) { 
   console.time(name); 
   for(var i = 0; i < n; i++) 
      fn(); 
   console.timeEnd(name);  
}

Results:

Andres (OP):

benchmark("Andres", function () { paramStrAndres("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
Andres: 505ms

Ryan/RWT:

benchmark("RWT", function () { paramStrRWT("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
RWT: 86ms

Daniel:

benchmark("Daniel", function () { paramStrDaniel("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
Daniel: 98ms

Sean:

benchmark("Sean", function () { paramStrSean("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
Sean: 40ms

Functions Tested:

Andres:

function paramStrAndres(str1, str2) {
    sArray = str2.split(",");

    for( var i = 0; i < sArray.length; i++ ) {
        var key = sArray[i].match(/(\w+)=/gi).toString().replace("=", ""),
        in_str1 = str1.search(key),
        replace_pattern = new RegExp(key+"=(\\w+)", "gi");

        if(in_str1 !== -1){                 
            str1 = str1.replace(replace_pattern, sArray[i]);
        } else {
            str1 = str1 + "," + sArray[i];
        }
    }
    return str1;
}

Ryan/RWT:

function paramStrRWT (str1, str2) {
 function parseParamString(str, obj) {
    var pairs = str.split(","),
        i = 0, l = pairs.length,
        pair;
    obj || (obj = {});
    for (; l > i; ++i) {
        pair = pairs[i].split("=", 2);
        obj[pair[0]] = pair[1];
    }
    return obj;
 }

 function buildParamString(obj) {
    var pairs = [], i;
    for (i in obj) {
        if (obj.hasOwnProperty(i)) {
            pairs.push(i + "=" + obj[i]);
        }
    }
    return pairs.join(",");
 }
 var resultObj = parseParamString(str2, parseParamString(str1));
 return buildParamString(resultObj);
}

Mine:

function paramStrDaniel(str1, str2) {
    var toObj = function (str) {
        var arr = str.split(","), obj = {};
        for (var i = 0; i < arr.length; i++) {
            var keyval = arr[i].split("=", 2);
            obj[keyval[0]] = keyval[1];
        }
        return obj;
    };

    var objToString = function (obj) {
        var stringBuilder = [];
        for (var k in obj) {
            stringBuilder.push(k+"="+obj[k]);
        }
        return stringBuilder.join(",");
    };

    var merge  = function (obj1, obj2) { // merge obj1 into obj2.. obj2 will be modified.
        for (var k in obj1) {
            obj2[k] = obj2[k] || obj1[k];
        }
        return obj2;
    };

    return objToString(merge(toObj(str1), toObj(str2)));
    }

Sean:

function paramStrSean(str1, str2) {
    var str3 = str2 + "," + str1, temp;

    while ((temp = str3.replace(/\b([a-z]+)(=.*)\b\1=[^,]*,?/, "$1$2")) != str3) {
        str3 = temp;
    }
    return str3;
    }

EDIT: I found it odd that my version was faster than Ryan's, considering they were similar. After looking into it, I see I made a boo-boo on the for loop (length -> arr.length). I've updated the benchmarks. That's what I get for not testing my code.

发布评论

评论列表(0)

  1. 暂无评论