<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何替換json對(duì)象中的key

          共 4399字,需瀏覽 9分鐘

           ·

          2021-06-08 20:37

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

          看到標(biāo)題你可能會(huì)想,如此簡(jiǎn)單的問題值得去探究嗎?如果我有一個(gè)json object,只需下面簡(jiǎn)單的幾行代碼就可以完成:
          var obj = {    "_id": "5078c3a803ff4197dc81fbfb",    "email": "[email protected]",    "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];

          是的,沒錯(cuò)!以上代碼可以很好地完成工作,從而將obj對(duì)象中的"_id"替換成"id"。

          在大多數(shù)情況下,這種方式不會(huì)帶來什么問題,但是,如果你需要將obj對(duì)象序列化到文檔中并比較差異,你就會(huì)看到問題。

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

          新添加的key默認(rèn)放在了最后,并且由于在替換過程中我們刪除了之前的key,所以導(dǎo)致序列化之后的obj與之前的obj存在較大的差異。


          那如何才能保證在最小差異的情況下實(shí)現(xiàn)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()函數(shù)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);

          上面這些例子有一部分可以達(dá)到我們的要求,另外有一部分和本文開頭給出的代碼基本等效(只是在執(zhí)行效率上略有差別)。

          但所有這些示例無一例外都不能同時(shí)滿足下面兩個(gè)要需:

          保留要替換的key在原json對(duì)象中的順序。既保證在JSON.stringify()執(zhí)行之后輸出的字符串中key的順序和原json對(duì)象是一致的。

          在原json對(duì)象上進(jìn)行修改,而不是返回一個(gè)新的json對(duì)象。某些情況下,我們需要對(duì)一個(gè)復(fù)雜json對(duì)象的子元素進(jìn)行修改,如果修改之后返回一個(gè)新的json對(duì)象,則無法保證這個(gè)新的對(duì)象會(huì)反應(yīng)到原json對(duì)象中。

          例如,jspath是一個(gè)可以通過domain-specific language (DSL)在給定的json對(duì)象中查找子元素的JavaScript庫,通過下面的代碼我們可以輕易地查找出obj對(duì)象中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對(duì)象是obj對(duì)象的一部分,意味著后續(xù)對(duì)res對(duì)象所做的任何修改都會(huì)反應(yīng)到obj對(duì)象中。

          如果我們對(duì)res中的某些key進(jìn)行替換,而返回一個(gè)新json對(duì)象的話,那么這個(gè)修改就不會(huì)反應(yīng)到obj對(duì)象中。

          基本思路:既然新添加的key默認(rèn)都會(huì)排在最后,那么索性遍歷json對(duì)象的所有key,然后將key一一替換為一個(gè)臨時(shí)名稱,隨后再將這個(gè)臨時(shí)名稱替換回來。

          在這個(gè)過程中,如果遇到真正需要替換的key,則不再進(jìn)行二次替換。下面是具體的代碼:

          var obj = {    "_id": "5078c3a803ff4197dc81fbfb",    "email": "[email protected]",    "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}`]; }});

          完成之后的效果如下圖:


          當(dāng)然,如果考慮通用性,可能需要遞歸遍歷給定的json對(duì)象。以上代碼只是給出了一個(gè)思路,考慮到執(zhí)行效率和安全性,這個(gè)并不是最佳方案,真實(shí)使用中我們可以逐步進(jìn)行完善。

          學(xué)習(xí)更多技能

          請(qǐng)點(diǎn)擊下方公眾號(hào)


          瀏覽 76
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日产毛片 | 一级片毛片 | 精品无码人妻一区二区 | 干屄在线观看 | 嫩草网址 |