重命名对象中的键

18
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,而数组中有许多这样的对象...


1
你为什么想要这样做?也许有更好的替代方案。 - James Montagne
可能是JavaScript:对象重命名键的重复问题。 - Ziggy
10个回答

19
也许可以像这样做?
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'));

13

你不能直接重命名属性。不过,你可以设置新的属性并取消旧的属性,从而间接地“重命名”它们:

function rename(obj, oldName, newName) {
    if(!obj.hasOwnProperty(oldName)) {
        return false;
    }

    obj[newName] = obj[oldName];
    delete obj[oldName];
    return true;
}

9

使用一行纯JavaScript实现不可变的键名重命名

虽然这不是最有效的重命名键名的方法,但是我认为它在某些方面很有趣:

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

第1点有时可能是必需的,如果您仍然需要使用原始数组。 第2点可能会引起兴趣,因为这里的某些示例代码超过30行。 第3点可能有教育目的,演示一些语言功能,这些功能没有像应该那样经常使用,考虑到它们的强大和广泛支持。

如果您创建了一个此类映射对象:

const m = { SPO2: 'O2' };

那么,您将能够轻松地在未来添加更多的密钥以便于重命名。

现在,可以在原生JS中创建一个一行代码:

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

Let's say that you have an array of objects:

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));

你的原始对象仍然保留在原始数组中。


1
我已经创建了一个重命名属性名称的好函数: https://github.com/meni181818/simpleCloneJS/blob/master/renameProperties.js 用法:
var renamedObj = renameProperties(sourceObject, {propName: 'propNEWname', anotherPropName: 'anotherPropNEWname'});

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

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

{{链接1: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;
}

在上面的函数的第三行,我们使用了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或Underscore.js或其他具有'each()'函数的库,你可以使用它来代替。只需将其替换为$.each(jquery)或_.each(underscore.js)即可。


1

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

首先,为了进行迭代,通常应该使用数组的map()函数。它比使用for (..)循环更少出错,并且比forEach()略微更好。一个for (..)循环通常会给你更好的性能(取决于JS引擎),但你需要处理相当大的数组才能注意到差异(即100k个元素的差异可能只有约10ms)。

其次,如果要重命名对象属性,则显而易见的解决方案是设置新键并删除旧键。这将起作用,但如果已定义自定义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语法编写的,所以几乎可以在任何地方运行。

这个回答不应该被踩!非常好的答案,而且运行得很好! - Mike

1
这是一个可以用于对象数组的函数,它接受一个旧键到新键的映射表。我大部分都是从这里复制了非常好的代码,并使其能够操作对象数组而不是单个对象。 代码
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 } ]

0
 addObjectResponse[0]["O2"] = addObjectResponse[0]["SPO2"];
 addObjectResponse[0]["SP02"] = null;

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

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


0

您可以添加 + 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

0
有点晚了,但是这个怎么样:
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}
})

0

不要改变这个对象键的名称,你可以创建另一个具有适当名称的对象,像这样:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接