我想出了以下方法,但我不确定它是否会比您的方法更快,因为涉及更多步骤。还有就是有点长……
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));
基准测试
我很无聊,所以我决定对所提供的这 3 种不同解决方案进行快速基准测试。
基准函数/测试:
function benchmark(name, fn, n) {
console.time(name);
for(var i = 0; i < n; i++)
fn();
console.timeEnd(name);
}
结果:
安德烈斯(OP):
benchmark("Andres", function () { paramStrAndres("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
Andres: 505ms
瑞安/RWT:
benchmark("RWT", function () { paramStrRWT("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
RWT: 86ms
丹尼尔:
benchmark("Daniel", function () { paramStrDaniel("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
Daniel: 98ms
肖恩:
benchmark("Sean", function () { paramStrSean("width=800,height=600,resizable=no,titlebar=no", "width=100,height=100"); }, 10000);
Sean: 40ms
测试的功能:
安德烈斯:
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;
}
瑞安/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);
}
我的:
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)));
}
肖恩:
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;
}
编辑:我觉得奇怪的是我的版本比 Ryan 的版本快,因为它们是相似的。在查看之后,我看到我在 for 循环 (length -> arr.length) 上做了一个嘘声。我已经更新了基准。这就是我没有测试我的代码的结果。