来源 | https://www.cnblogs.com/jaxu/archive/2021/06/01/14836088.html

看到标题你可能会想,如此简单的问题值得去探究吗?如果我有一个json object,只需下面简单的几行代码就可以完成:

var obj = {    "_id": "5078c3a803ff4197dc81fbfb",    "email": "user1@gmail.com",    "image": "some_image_url",    "name": "Name 1"};
var new_key = "id";var old_key = "_id";
obj[new_key] = obj[old_key];delete obj[old_key];

是的,没错!以上代码可以很好地完成工作,从而将obj对象中的"_id"替换成"id"。

在大多数情况下,这种方式不会带来什么问题,但是,如果你需要将obj对象序列化到文档中并比较差异,你就会看到问题。

// 修改之前的obj{    "_id": "5078c3a803ff4197dc81fbfb",    "email": "user1@gmail.com",    "image": "some_image_url",    "name": "Name 1"}
// 修改之后的obj // jsON.stringify(obj, null, "\t"){    "email": "user1@gmail.com",    "image": "some_image_url",    "name": "Name 1",    "id": "5078c3a803ff4197dc81fbfb"}

新添加的key默认放在了最后,并且由于在替换过程中我们删除了之前的key,所以导致序列化之后的obj与之前的obj存在较大的差异。

那如何才能保证在最小差异的情况下实现key的替换呢?下面是我找到的一些方法:

Object.prototype.renameProperty = function (oldName, newName) {     // Do nothing if the names are the same     if (oldName === newName) {         return this;     }    // Check for the old property name to avoid a ReferenceError in strict mode.    if (this.hasOwnProperty(oldName)) {        this[newName] = this[oldName];        delete this[oldName];    }    return this;};
function renameKeys(obj, newKeys) {  const keyValues = Object.keys(obj).map(key => {    const newKey = newKeys[key] || key;    return { [newKey]: obj[key] };  });  return Object.assign({}, ...keyValues);}const obj = { a: "1", b: "2" };const newKeys = { a: "A", c: "C" };const renamedObj = renameKeys(obj, newKeys);console.log(renamedObj);// {A:"1", b:"2"}
// 使用lodash的_.mapKeys()函数var user = {  name: "Andrew",  id: 25,  reported: false};
var renamed = _.mapKeys(user, function(value, key) {  return key + "_" + user.id;});
console.log(renamed);
var str = JSON.stringify(object);str = str.replace(/oldKey/g, 'newKey');str = str.replace(/oldKey2/g, 'newKey2');
object = JSON.parse(str);
function renameObjectKey(oldObj, oldName, newName) {    const newObj = {};Object.keys(oldObj).forEach(key => {        const value = oldObj[key];if (key === oldName) {            newObj[newName] = value;        } else {            newObj[key] = value;        }    });return newObj;}
data = {key1: "value1", key2: "value2", key3: "value3"};
keyMap = {key1: "firstkey", key2: "secondkey", key3: "thirdkey"};
mappedData = Object.keys(keyMap).reduce((obj,k) => Object.assign(obj, { [keyMap[k]]: data[k] }),{});
console.log(mappedData);

上面这些例子有一部分可以达到我们的要求,另外有一部分和本文开头给出的代码基本等效(只是在执行效率上略有差别)。

但所有这些示例无一例外都不能同时满足下面两个要需:

保留要替换的key在原json对象中的顺序。既保证在JSON.stringify()执行之后输出的字符串中key的顺序和原json对象是一致的。

在原json对象上进行修改,而不是返回一个新的json对象。某些情况下,我们需要对一个复杂json对象的子元素进行修改,如果修改之后返回一个新的json对象,则无法保证这个新的对象会反应到原json对象中。

例如,jspath是一个可以通过domain-specific language (DSL)在给定的json对象中查找子元素的JavaScript库,通过下面的代码我们可以轻易地查找出obj对象中automobiles属性中maker === "Honda"并且year > 2009的元素。

var obj = {    "automobiles" : [        { "maker" : "Nissan", "model" : "Teana", "year" : 2011 },        { "maker" : "Honda", "model" : "Jazz", "year" : 2010 },        { "maker" : "Honda", "model" : "Civic", "year" : 2007 },        { "maker" : "Toyota", "model" : "Yaris", "year" : 2008 },        { "maker" : "Honda", "model" : "Accord", "year" : 2011 }    ],    "motorcycles" : [{ "maker" : "Honda", "model" : "ST1300", "year" : 2012 }]};
var res = JSPath.apply('.automobiles{.maker === "Honda" && .year > 2009}', obj);
// res: [{ "maker" : "Honda", "model" : "Jazz", "year" : 2010 }, { "maker" : "Honda", "model" : "Accord", "year" : 2011 }]

注意这里返回的res对象是obj对象的一部分,意味着后续对res对象所做的任何修改都会反应到obj对象中。

如果我们对res中的某些key进行替换,而返回一个新json对象的话,那么这个修改就不会反应到obj对象中。

基本思路:既然新添加的key默认都会排在最后,那么索性遍历json对象的所有key,然后将key一一替换为一个临时名称,随后再将这个临时名称替换回来。

在这个过程中,如果遇到真正需要替换的key,则不再进行二次替换。下面是具体的代码:

var obj = {    "_id": "5078c3a803ff4197dc81fbfb",    "email": "user1@gmail.com",    "image": "some_image_url",    "name": "Name 1"};
var new_key = "id";var old_key = "_id";
Object.keys(obj).forEach(key => {    if (key === old_key) {        obj[new_key] = obj[key];        delete obj[key];    } else {        obj[`_${key}`] = obj[key];        delete obj[key];obj[`${key}`] = obj[`_${key}`];        delete obj[`_${key}`];    }});

完成之后的效果如下图:

当然,如果考虑通用性,可能需要递归遍历给定的json对象。以上代码只是给出了一个思路,考虑到执行效率和安全性,这个并不是最佳方案,真实使用中我们可以逐步进行完善。

学习更多技能

请点击下方公众号

如何替换json对象中的key相关推荐

  1. JS(JQEERY) 获取JSON对象中的KEY VALUE

    var json= { "Type": "Coding", "Height":100 };for (var key in json){ale ...

  2. 检查密钥是否存在于json对象中

    本文翻译自:Check if a key exists inside a json object amt: "10.00" email: "sam@gmail.com&q ...

  3. JS 遍历JSON对象中的键值对

    对象:一组无序属性的集合,属性的值可以是任意的类型: json也是对象,数据都是成对的,也就是键值对: json实际上就是一组格式化后的字符串数据. 遍历JSON对象中的数据,可通过for-in循环实 ...

  4. XE3随笔6:SuperObject 的 JSON 对象中还可以包含 方法

    SuperObject 的 JSON 对象中还可以包含 "方法", 这太有意思了; 其方法的格式是: procedure Method(const This, Params: IS ...

  5. JSON对象中的函数调用,JSON格式的字符串对应的函数调用方法

    json对象中的函数调用:直接使用 json变量名+函数名+()进行调用,特别注意这对括号:如果是获取到的json格式的字符串,想要调用它的方法前,需要先将该字符串转换成json对象,在调用对应的方法 ...

  6. js基础知识:es6中,当对象中的key名称为一个变量时,需要用`[]`括起来

    es6中,当对象中的key名称为一个变量时,需要用[]括起来

  7. json对象遍历输出key和value

    js遍历json对象 原生js遍历json对象 遍历json对象: 无规律: <11script> var json = [ {dd:'SB',AA:'东东',re1:123}, {ccc ...

  8. JS-JSON-获取JSON对象中的数据展示到表格里

    JS-JSON-获取JSON对象中的数据展示到表格里 1.要求 点击按钮,将学生信息展示到表格里,并显示总记录条数. 2.实现思路 创建JSON对象 先创建一个JSON对象data,有总人数total ...

  9. 移除Java对象中的属性_移除/添加 JSON对象中的某个属性

    因为JSON完全是动态的,所以给一个JSON对象添加一个属性是很简单的,如: var json = {}; json.username='xtayfjpk'; 这样就为json对象添加了一个名为use ...

最新文章

  1. Php Fatal error: Allowed memory size of 33554432 bytes exhausted 的解决办法
  2. WINDOWS中, 如何查看一个运行中的程序是64位还是32位的
  3. vue-自定义组件传值
  4. Python学习一——Python下载安装
  5. springbot 注入多实例
  6. mysql数据库的备份和二进制日志恢复
  7. .Net环境下的缓存技术介绍 (转)
  8. 【LeetCode笔记】剑指 Offer 56 . 数组中数字出现的次数(Java、位运算)
  9. ZetCode Python 教程
  10. 兄弟们别加班了,老板不会因为你拼命写代码而感谢你啊~有木有啊
  11. 谈谈JavaScript中的数组、集合及效率
  12. 表单美化+html+css
  13. linux 执行命令详细步骤,Linux命令行使用教程
  14. 金融风控实战——金融风控与反欺诈业务详解
  15. 第十二周练兵区——编程题——不计入总分
  16. Mybatis中如何实现一对一,一对多的关联查询?
  17. Hisat2-Stringtie-DESeq2复现Transcript-level expression analysis of RNA-seq experiments with ...
  18. 微前端框架哪个好?QianKun还是MicroApp
  19. STM32实现LED流水灯
  20. 上传图片到到本地图片服务器操作方式

热门文章

  1. android三星note20.6,三星Galaxy Note 20 Ultra依旧是“安卓机皇”,用过的都说好
  2. html保存时出现nul,c# – 有时保存的文件只包含NUL字符
  3. Assert 的用法
  4. ikbc键盘解锁上锁 解决win键失灵的问题
  5. ⑭霍兰德RS*型如何选专业?高考志愿填报选专业
  6. 可编程交换机P4网络资源
  7. mysql时间类型之按时间排序精确到毫秒
  8. 概率论与数理统计:随机变量、分布律,分布函数,密度函数
  9. 客户端与服务器相关概念
  10. studiolibrary安装_初学者daz studio中文基础安装布局教程