我收到来自网络服务的响应,并希望将响应中的某些值替换为我的自定义值。
一种方法是编写一个树遍历器,然后检查该值并替换为我的自定义值
所以响应是这样的:
[
{
"name": "n1",
"value": "v1",
"children": [
{
"name": "n2",
"value": "v2"
}
]
},
{
"name": "n3",
"value": "v3"
}
]
现在我的自定义 map 是这样的
const map = {
"v1": "v11",
"v2": "v22",
"v3": "v33"
};
我想要的只是
[
{
"name": "n1",
"value": "v11",
"children": [
{
"name": "n2",
"value": "v22"
}
]
},
{
"name": "n3",
"value": "v33"
}
]
我在想是否可以对我的响应进行字符串化,然后使用值映射中的自定义构建正则表达式替换值。
- 与树遍历器相比,它会更快吗?
- 如果是,我该怎么做?
有点像这样
originalString.replace(regexp, function (replacement))
最佳答案
树遍历更快
请注意,在正则表达式实现中可以更有效地完成某些事情,但我仍然认为还有一些瓶颈需要解释。
为什么正则表达式很慢:
正则表达式速度较慢的原因可能还有很多,但我将解释至少一个重要原因:
当您使用正则表达式进行查找和替换时,您每次都会创建新字符串并执行匹配。正则表达式 can be very expensive而且我的实现并不是特别便宜。
为什么树遍历更快:
在树遍历中,我直接改变对象。这根本不需要创建新的 string
对象或任何新对象。我们也不会每次都对整个字符串执行完整搜索。
结果
运行下面的性能测试。测试使用console.time来记录需要多长时间。看到树的遍历速度快了很多。
function usingRegex(obj, map) {
return JSON.parse(Object.keys(map).map(oldValue => ({
oldValue,
newValue: map[oldValue]
})).reduce((json, {
oldValue,
newValue
}) => {
return json.replace(
new RegExp(`"value":"(${oldValue})"`),
() => `"value":"${newValue}"`
);
}, JSON.stringify(obj)));
}
function usingTree(obj, map) {
function traverse(children) {
for (let item of children) {
if (item && item.value) {
// get a value from a JS object is O(1)!
item.value = map[item.value];
}
if (item && item.children) {
traverse(item.children)
}
}
}
traverse(obj);
return obj; // mutates
}
const obj = JSON.parse(`[
{
"name": "n1",
"value": "v1",
"children": [
{
"name": "n2",
"value": "v2"
}
]
},
{
"name": "n3",
"value": "v3"
}
]`);
const map = {
"v1": "v11",
"v2": "v22",
"v3": "v33"
};
// show that each function is working first
console.log('== TEST THE FUNCTIONS ==');
console.log('usingRegex', usingRegex(obj, map));
console.log('usingTree', usingTree(obj, map));
const iterations = 10000; // ten thousand
console.log('== DO 10000 ITERATIONS ==');
console.time('regex implementation');
for (let i = 0; i < iterations; i += 1) {
usingRegex(obj, map);
}
console.timeEnd('regex implementation');
console.time('tree implementation');
for (let i = 0; i < iterations; i += 1) {
usingTree(obj, map);
}
console.timeEnd('tree implementation');
关于javascript - 替换 json/jsObject/string 中的多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43108995/