替换json对象中的key最佳方案

 更新时间:2021年6月2日 10:00  点击:2899

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

  看到标题你可能会想,如此简单的问题值得去探究吗?如果我有一个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最佳方案的详细内容,更多关于替换json对象中的key的资料请关注猪先飞其它相关文章!

[!--infotagslink--]

相关文章

  • java8如何用Stream查List对象某属性是否有重复

    这篇文章主要介绍了java8如何用Stream查List对象某属性是否有重复的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
  • @CacheEvict 清除多个key的实现方式

    这篇文章主要介绍了@CacheEvict 清除多个key的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13
  • gin 获取post请求的json body操作

    这篇文章主要介绍了gin 获取post请求的json body操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-15
  • R语言 如何删除指定变量或对象

    这篇文章主要介绍了R语言删除指定变量或对象的操作方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06
  • 详解Mysql中的JSON系列操作函数

    新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
  • Json格式详解

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成...2021-11-05
  • C#使用Http Post方式传递Json数据字符串调用Web Service

    这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26
  • 浅谈redis key值内存消耗以及性能影响

    这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
  • @Cacheable 拼接key的操作

    这篇文章主要介绍了@Cacheable 拼接key的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13
  • js遍历json的key和value的实例

    下面小编就为大家带来一篇js遍历json的key和value的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-01-26
  • JavaScript预解析,对象详解

    这篇文章主要介绍了JavaScript预解析,对象的的相关资料,小编觉得这篇文章写的还不错,需要的朋友可以参考下,希望能够给你带来帮助...2021-11-10
  • 牛叉的Jquery――Jquery与DOM对象的互相转换及DOM的三种操作

    只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的dom操作。这就需要我们知道如何将jQuery对象和DOM的相互转换的方法。1...2015-10-30
  • 详解.NET Core 3.0 里新的JSON API

    这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • uniapp微信小程序:key失效的解决方法

    这篇文章主要介绍了uniapp微信小程序:key失效的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-20
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 基于Vue+Openlayer实现动态加载geojson的方法

    本文通过实例代码给大家介绍基于Vue+Openlayer实现动态加载geojson的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-09-01
  • js如何打印object对象

    js调试中经常会碰到输出的内容是对象而无法打印的时候,光靠alert只能打印出object标示,却不能打印出来里面的内容,甚是不方便,于是各方面整理总结了如下一个函数,能够将数组或者对象这类的结果一一打印出来,具体代码如下: fu...2015-10-21
  • 解决HttpPost+json请求---服务器中文乱码及其他问题

    这篇文章主要介绍了解决HttpPost+json请求---服务器中文乱码及其他问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22
  • jquery对Json的各种遍历方法总结(必看篇)

    下面就为大家带来一篇jquery对Json的各种遍历方法总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-02