【问题标题】:Rename the keys in an object重命名对象中的键
【发布时间】:2011-08-04 13:18:13
【问题描述】:
var addObjectResponse = [{
    'SPO2': '222.00000',
    'VitalGroupID': 1152,
    'Temperature': 36.6666666666667,
    'DateTimeTaken': '/Date(1301494335000-0400)/',
    'UserID': 1,
    'Height': 182.88,
    'UserName': 'Admin',
    'BloodPressureDiastolic': 80,
    'Weight': 100909.090909091,
    'TemperatureMethod': 'Oral',
    'Resprate': 111,
    'HeartRate': 111,
    'BloodPressurePosition': 'Standing',
    'VitalSite': 'Popliteal',
    'VitalID': 1135,
    'Laterality': 'Right',
    'HeartRateRegularity': 'Regular',
    'HeadCircumference': '',
    'BloodPressureSystolic': 120,
    'CuffSize': 'XL',
}];

如何重命名键...像SPO2变成O2...数组中有这么多对象...

【问题讨论】:

标签: javascript


【解决方案1】:

也许是这样的?

var i, len = addObjectResponse.length;
for (i = 0; i < len; i++) {
    addObjectResponse[i]['O2'] = addObjectResponse[i]['SPO2'];
    delete addObjectResponse[i]['SPO2'];
}

addObjectResponse = addObjectResponse.map(function (obj) {
    obj['O2'] = obj['SP02'];
    delete obj['S02'];
    return obj;
});

for (let obj of addObjectResponse) {
    obj['O2'] = obj['SP02'];
    delete obj['S02'];
}

function renameProperty(obj, fromKey, toKey) {
    obj[toKey] = obj[fromKey];
    delete obj[fromKey];
}

addObjectResponse.forEach(obj => renameProperty(obj, 'SP02', 'O2'));

【讨论】:

    【解决方案2】:

    您不能直接重命名属性。但是,您可以设置新属性并取消设置旧属性,间接“重命名”它们:

    function rename(obj, oldName, newName) {
        if(!obj.hasOwnProperty(oldName)) {
            return false;
        }
    
        obj[newName] = obj[oldName];
        delete obj[oldName];
        return true;
    }
    

    【讨论】:

      【解决方案3】:

      vanilla JS one-liner 中的不可变键重命名

      这可能不是重命名密钥的最有效方法,但我认为它在某些方面很有趣:

      1. 它不会改变原始对象
      2. 只需要一行原生 JavaScript
      3. 它演示了现代语法的使用

      如果您仍然需要使用原始数组,有时可能需要 No.1。 考虑到这里的一些示例有超过 30 行代码这一事实,第 2 项可能会很有趣。 考虑到它们的强大功能和广泛支持的事实,No.3 可能用于展示语言中一些没有按应有的频率使用的特性的教育目的。

      如果你像这样创建一个映射对象:

      const m = { SPO2: 'O2' };
      

      那么您以后就可以轻松添加更多键来重命名。

      现在,可以在 vanilla JS 中创建一个单行:

      const t = o => Object.assign(...Object.keys(o).map(k => ({ [m[k] || k]: o[k] })));
      

      假设你有一个对象数组:

      const a = [{
        'SPO2': '222.00000',
        'VitalGroupID': 1152,
      }, {
        'SPO2': '333.00000',
        'VitalGroupID': 1153,
      }, {
        'SPO2': '444.00000',
        'VitalGroupID': 1154,
      }];
      

      您可以像这样使用a.map(t) 获得一个新数组:

      console.log('Before:', a);
      console.log('After:', a.map(t));
      

      您的原始对象在原始数组中仍然完好无损。

      【讨论】:

        【解决方案4】:

        我创建了一个很好的函数来重命名属性名称:https://github.com/meni181818/simpleCloneJS/blob/master/renameProperties.js

        用法:

        var renamedObj = renameProperties(sourceObject, {propName: 'propNEWname', anotherPropName: 'anotherPropNEWname'});
        

        我的函数也处理数组内的对象,所以在你的情况下你可以这样做:

        addObjectResponse = renameProperties(addObjectResponse, {SPO2: 'O2'});
        

        DEMO


        function renameProperties(sourceObj, replaceList, destObj) {
            destObj = destObj || {};
            each(sourceObj, function(key) {
                if(sourceObj.hasOwnProperty(key)) {
                    if(sourceObj[key] instanceof Array) {
                        if(replaceList[key]) {
                            var newName = replaceList[key];
                            destObj[newName] = [];
                            renameProperties(sourceObj[key], replaceList, destObj[newName]);
                        } else if(!replaceList[key]) {
                            destObj[key] = [];
                            renameProperties(sourceObj[key], replaceList, destObj[key]);
                        }
                    } else if(typeof sourceObj[key] === 'object') {
                        if(replaceList[key]) {
                            var newName = replaceList[key];
                            destObj[newName] = {};
                            renameProperties(sourceObj[key], replaceList, destObj[newName]);
                        } else if(!replaceList[key]) {
                            destObj[key] = {};
                            renameProperties(sourceObj[key], replaceList, destObj[key]);
                        }             
                    } else {
                        if(replaceList[key]) {
                            var newName = replaceList[key];
                            destObj[newName] = sourceObj[key];
                        } else if(!replaceList[key]) {
                            destObj[key] = sourceObj[key];
                        }
                    }
                }
            });
        
            return destObj;
        }
        

        在上面函数的第 3 行,我们使用了each() 函数。这是:

        function each(objOrArr, callBack) {
            if(objOrArr instanceof Array) {
                for(var i = 0; i < objOrArr.length; i++) {
                    callBack(i);
                }
            } else if(typeof objOrArr === 'object') {
                for(var prop in objOrArr) {
                    // if the property really exist
                    if(objOrArr.hasOwnProperty(prop)) {
                        callBack(prop);
                    }
                }
            }
        }
        

        注意:如果你使用的是 Jquery OR underscore.js 或者其他有 'each()' 功能的库,你可以使用它来代替。只需回复$.each (jquery) 或 _.each (underscore.js)。

        【讨论】:

          【解决方案5】:

          好的,你在这里做了两件事,遍历数组和重命名对象的属性。

          首先,要进行迭代,您通常应该使用数组map() function。 我认为它比使用for ( .. ) 循环更不容易出错,并且比forEach() 稍微好一点。 for ( .. ) 循环通常会给你更好的性能(取决于 JS 引擎),但你需要处理相当大的数组才能注意到(即 100k 元素可能有约 10 毫秒的差异)。

          其次,要重命名对象属性,显而易见的解决方案是设置新键并删除旧键。 这将起作用,但如果已定义自定义 getter 或 setter,则不会始终为您提供与旧属性完全相同的属性。 如果您正在创建一个通用的辅助函数来完成这种工作,那么您最好使用 Object.defineProperty()Object.getOwnPropertyDescriptor().

          把这些放在一起,我们得到:

          function renameKeyInObjArray (array, oldKey, newKey) {
              return array.map(function (obj) {
                  Object.defineProperty(obj, newKey, Object.getOwnPropertyDescriptor(obj, oldKey));
                  delete obj[oldKey];
                  return obj;
              });
          }
          
          // Use our new function to process the array
          renameKeyInObjArray(addObjectResponse, 'SPO2', 'O2');
          

          这个函数通过引用更新数组的内容,同时也返回一个对数组的引用,所以可以被链式化。它也是用 ES5.1 语法编写的,所以几乎可以在任何地方运行。

          【讨论】:

          • 这不应该被否决!很好的答案,效果很好!
          【解决方案6】:

          这是一个处理对象数组并将旧对象键映射到新对象键的方法。

          我主要是从here 复制了非常好的代码,只是让它对对象数组而不是单个对象进行操作。

          代码

          const renameKeys = (keysMap, objArr) =>
            (renamedArr = objArr.map((obj) =>
              Object.keys(obj).reduce(
                (acc, key) => ({
                  ...acc,
                  ...{ [keysMap[key] || key]: obj[key] },
                }),
                {}
              )
            ));
          

          示例

          renameKeys({ tWo: 'two', FreE: 'three' }, [
            { one: 1, tWo: 2, three: 3 },
            { one: 100, two: 200, FreE: 300 },
          ]);
          [ { one: 1, two: 2, three: 3 }, { one: 100, two: 200, three: 300 } ]
          

          【讨论】:

            【解决方案7】:

            您可以添加 + delete(阅读 IE 警告);

            var addObjectResponse = [{
                'SPO2': '222.00000',
                'VitalGroupID': 1152
            }]
            
            for (var k in addObjectResponse[0])
                log(k)
            
            >>SPO2
            >>VitalGroupID
            
            addObjectResponse[0]['O2'] = addObjectResponse[0]['SPO2']
            delete addObjectResponse[0]['SPO2']
            
            for (var k in addObjectResponse[0])
                log(k)
            
            >>VitalGroupID
            >>O2
            

            【讨论】:

              【解决方案8】:
               addObjectResponse[0]["O2"] = addObjectResponse[0]["SPO2"];
               addObjectResponse[0]["SP02"] = null;
              

              [0] 是必需的,因为 addObjectResponse 设置为一个包含一个元素的数组,其中包含一个对象。你对哪些键将被重命名或如何重命名有任何规则吗?

              编辑:我误解了 OP,认为“许多对象”指的是对象中需要重命名的许多键,而不是数组中的许多对象,每个对象都需要重命名一个键。

              【讨论】:

                【解决方案9】:

                您可以创建另一个具有正确名称的对象,而不是重命名此对象键,如下所示:

                var obj={wrongKeyName:'test'};
                var obj2 = {}
                obj2.rightKeyName = obj.wrongKeyName;
                console.log(obj2);
                

                【讨论】:

                  【解决方案10】:

                  这里的游戏有点晚了,但是这样的事情怎么样:

                  const newAddObjectResponse = addObjectResponse.map((obj) => {
                      const {SPO2: O2, ...rest} = obj
                      return {O2, ...rest}
                  })
                  

                  如果你想替换原来的数组,那么你可以这样做:

                  let addObjectResponse = [
                      {
                          SPO2: '222.00000',
                          VitalGroupID: 1152,
                          Temperature: 36.6666666666667,
                          DateTimeTaken: '/Date(1301494335000-0400)/',
                          UserID: 1,
                          Height: 182.88,
                          UserName: 'Admin',
                          BloodPressureDiastolic: 80,
                          Weight: 100909.090909091,
                          TemperatureMethod: 'Oral',
                          Resprate: 111,
                          HeartRate: 111,
                          BloodPressurePosition: 'Standing',
                          VitalSite: 'Popliteal',
                          VitalID: 1135,
                          Laterality: 'Right',
                          HeartRateRegularity: 'Regular',
                          HeadCircumference: '',
                          BloodPressureSystolic: 120,
                          CuffSize: 'XL',
                      },
                  ]
                  
                  addObjectResponse = addObjectResponse.map((obj) => {
                      const {SPO2: O2, ...rest} = obj
                      return {O2, ...rest}
                  })
                  

                  【讨论】:

                    猜你喜欢
                    • 2020-10-14
                    • 2011-06-06
                    • 1970-01-01
                    • 2016-09-04
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多