javascript - 替换 json/jsObject/string 中的多个值

标签 javascript json regex string replace

我收到来自网络服务的响应,并希望将响应中的某些值替换为我的自定义值。

一种方法是编写一个树遍历器,然后检查该值并替换为我的自定义值

所以响应是这样的:

[
  {
    "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"
  }
]

我在想是否可以对我的响应进行字符串化,然后使用值映射中的自定义构建正则表达式替换值。

  1. 与树遍历器相比,它会更快吗?
  2. 如果是,我该怎么做?

有点像这样

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/

相关文章:

javascript - Javascript 的正面回顾

javascript - 自透明对象仅从一侧看起来正确

javascript - 如何使用箭头键浏览 <li> 元素 - jQuery?

javascript - 如何从弹出窗口获取url?

php - 如何从 MySQL 数据库实时/动态生成 JSON

php - AHAH 是否存在安全风险?

regex - 带重定向的 URL 掩码/伪装

php - 如何在 PHP 中使用正则表达式解析 Apache 日志

javascript - 使用命名空间模块中的 mapState 和 mapMutations

javascript - 如何获取数组中所有json键