JavaScript:对象重命名密钥

时间:2011-01-10 14:29:21

标签: javascript object key rename

是否有一种聪明的(即优化的)方法来重命名javascript对象中的键?

非优化方式是:

o[ new_key ] = o[ old_key ];
delete o[ old_key ];

28 个答案:

答案 0 :(得分:153)

我认为最完整(也是最正确)的做法是:

if (old_key !== new_key) {
    Object.defineProperty(o, new_key,
        Object.getOwnPropertyDescriptor(o, old_key));
    delete o[old_key];
}

此方法可确保重命名的属性与原始属性的行为相同

此外,在我看来,将此包装成函数/方法并将其放入Object.prototype的可能性与您的问题无关。

答案 1 :(得分:87)

您可以将工作包装在函数中并将其分配给Object原型。也许使用流畅的界面风格来进行多次重命名流程。

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

ECMAScript 5具体

我希望语法不是很复杂但是拥有更多控制权肯定很好。

Object.defineProperty(
    Object.prototype, 
    'renameProperty',
    {
        writable : false, // Cannot alter this property
        enumerable : false, // Will not show up in a for-in loop.
        configurable : false, // Cannot be deleted via the delete operator
        value : 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;
        }
    }
);

答案 2 :(得分:38)

如果您要改变源对象,ES6可以在一行中完成。

delete Object.assign(o, {[newKey]: o[oldKey] })[oldKey];

如果要创建新对象,可以使用两行。

const newObject = {};
delete Object.assign(newObject, o, {[newKey]: o[oldKey] })[oldKey];

答案 3 :(得分:29)

如果有人需要重命名属性列表:

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"}

答案 4 :(得分:17)

我想使用ES6(ES2015)方式!

  

我们需要跟上时代的步伐!



const old_obj = {
    k1: `111`,
    k2: `222`,
    k3: `333`
};
console.log(`old_obj =\n`, old_obj);
// {k1: "111", k2: "222", k3: "333"}


/**
 * @author xgqfrms
 * @description ES6 ...spread & Destructuring Assignment
 */

const {
    k1: kA, 
    k2: kB, 
    k3: kC,
} = {...old_obj}

console.log(`kA = ${kA},`, `kB = ${kB},`, `kC = ${kC}\n`);
// kA = 111, kB = 222, kC = 333

const new_obj = Object.assign(
    {},
    {
        kA,
        kB,
        kC
    }
);

console.log(`new_obj =\n`, new_obj);
// {kA: "111", kB: "222", kC: "333"}




demo screen shortcut

答案 5 :(得分:5)

如果您不想改变数据,请考虑此功能......

renameProp = (oldProp, newProp, {[oldProp]:old, ...others}) => ({
    [newProp]: old,
    ...others
})

Yazeed Bzadough的详尽解释 https://medium.com/front-end-hacking/immutably-rename-object-keys-in-javascript-5f6353c7b6dd

答案 6 :(得分:4)

我做这样的事情:

function renameKeys(dict, keyMap) {
  return _.reduce(dict, function(newDict, val, oldKey) {
    var newKey = keyMap[oldKey] || oldKey
    newDict[newKey] = val 
    return newDict
  }, {})
}

答案 7 :(得分:4)

重命名键但避免更改原始对象参数

oldJson=[{firstName:'s1',lastName:'v1'},
         {firstName:'s2',lastName:'v2'},
         {firstName:'s3',lastName:'v3'}]

newJson = oldJson.map(rec => {
  return {
    'Last Name': rec.lastName,
    'First Name': rec.firstName,  
     }
  })
output: [{Last Name:"v1",First Name:"s1"},
         {Last Name:"v2",First Name:"s2"},
         {Last Name:"v3",First Name:"s3"}]

最好有一个新数组

答案 8 :(得分:4)

只需在您喜欢的编辑器<3

中尝试
const obj = {1: 'a', 2: 'b', 3: 'c'}

const OLD_KEY = 1
const NEW_KEY = 10

const { [OLD_KEY]: replaceByKey, ...rest } = obj
const new_obj = {
  ...rest,
  [NEW_KEY]: replaceByKey
}

答案 9 :(得分:3)

我想说从概念的角度来看,将旧对象(来自Web服务的对象)保留原样会更好,并将所需的值放在新对象中。我假设您正在某个时刻提取特定字段,如果不是在客户端上,那么至少在服务器上。您选择使用与Web服务相同的字段名称(仅为小写)这一事实并未真正改变这一点。所以,我建议做这样的事情:

var myObj = {
    field1: theirObj.FIELD1, 
    field2: theirObj.FIELD2,
    (etc)
}

当然,我在这里做了各种各样的假设,这可能不是真的。如果这不适用于你,或者它太慢了(是不是?我没有测试过,但我认为随着字段数量的增加,差异会变小),请忽略所有这些:)

如果你不想这样做,而且你只需要支持特定的浏览器,你也可以使用新的getter来返回“uppercase(field)”:见http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/及其上的链接页面了解更多信息。

编辑:

令人难以置信的是,这几乎是我工作时FF3.5的两倍。请参阅:http://jsperf.com/spiny001

答案 10 :(得分:3)

另一种方法是使用最强大的 REDUCE 方法。

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

答案 11 :(得分:3)

为每个键添加前缀:

const obj = {foo: 'bar'}

const altObj = Object.fromEntries(
  Object.entries(obj).map(([key, value]) => 
    // Modify key here
    [`x-${key}`, value]
  )
)

// altObj = {'x-foo': 'bar'}

答案 12 :(得分:3)

使用对象解构和散布运算符的变体:

    const old_obj = {
        k1: `111`,
        k2: `222`,
        k3: `333`
    };


// destructuring, with renaming. The variable rest will hold those values not assigned to kA, kB, or kC.
    const {
        k1: kA, 
        k2: kB, 
        k3: kC,
        ...rest
    } = old_obj;


// now create a new object, with shorthand properties **kA, kB, kC**; 
// spread the remaining properties in the **rest** variable
const newObj = {kA, kB, kC, ...rest};

答案 13 :(得分:2)

您可以尝试使用_.mapKeys

var user = {
  name: "Andrew",
  id: 25,
  reported: false
};

var renamed = _.mapKeys(user, function(value, key) {
  return key + "_" + user.id;
});

console.log(renamed);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

答案 14 :(得分:2)

本页列出的一些解决方案有一些副作用:

  1. 影响对象中键的位置,将其添加到底部(如果这对您很重要)
  2. 无法在IE9 +中运行(再次,如果这对您很重要)
  3. 这是一个解决方案,它将密钥的位置保持在同一位置,并且在IE9 +中兼容,但必须创建一个新对象,可能不是最快的解决方案:

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

    请注意:IE9可能不支持严格模式下的每个

答案 15 :(得分:2)

如果要保留迭代顺序(插入顺序),这里有一个建议:

const renameObjectKey = (object, oldName, newName) => {

  const updatedObject = {}

  for(let key in object) {
      if (key === oldName) {
          newObject[newName] = object[key]
      } else {
          newObject[key] = object[key]
      }
  }

  object = updatedObject
}

答案 16 :(得分:1)

这里是使用重命名键创建新对象的示例。

PackageInfo info = this.getPackageManager().getPackageInfo(this.getPackageName(), PackageManager.GET_SIGNATURES);

答案 17 :(得分:1)

虽然这并没有为重命名密钥提供更好的解决方案,但它提供了一种快速简便的ES6方法来重命名对象中的所有密钥,同时不改变它们包含的数据。

let b = {a: ["1"], b:["2"]};
Object.keys(b).map(id => {
  b[`root_${id}`] = [...b[id]];
  delete b[id];
});
console.log(b);

答案 18 :(得分:1)

就个人而言,最有效的方法是重命名对象中的键而不实现额外的重插件和轮子:

var str = JSON.stringify(object);
str = str.replace(/oldKey/g, 'newKey');
str = str.replace(/oldKey2/g, 'newKey2');

object = JSON.parse(str);

如果您的对象具有无效结构,您也可以将其包装在try-catch中。完美的工作:)

答案 19 :(得分:1)

var myObject = { oldKey: "value" };

myObject = JSON.parse(JSON.stringify(myObject).replace("oldKey", "newKey"));

答案 20 :(得分:0)

我认为您的方法已经过优化。但是您最终将获得重新排序的密钥。新创建的密钥将添加到末尾。我知道您永远不应该依赖键顺序,但是如果您需要保留键顺序,则将需要遍历所有键并一个一个地构造新对象,并在此过程中替换有问题的键。

赞:

var new_o={};
for (var i in o)
{
   if (i==old_key) new_o[new_key]=o[old_key];
   else new_o[i]=o[i];
}
o=new_o;

答案 21 :(得分:0)

此处的大多数答案都无法维持JS对象键值对的顺序。例如,如果您要在屏幕上使用某种形式的对象键-值对,那么保留对​​象条目的顺序就很重要。

ES6循环遍历JS对象并将键值对替换为具有修改后的键名的新键对的方法如下:

let newWordsObject = {};

Object.keys(oldObject).forEach(key => {
  if (key === oldKey) {
    let newPair = { [newKey]: oldObject[oldKey] };
    newWordsObject = { ...newWordsObject, ...newPair }
  } else {
    newWordsObject = { ...newWordsObject, [key]: oldObject[key] }
  }
});

该解决方案通过将新条目添加到旧条目的位置来保留条目的顺序。

答案 22 :(得分:0)

这是我对pomber功能的一个小修改; 为了能够采用对象数组而不是单独的对象,还可以激活索引。也可以通过数组分配“键”

function renameKeys(arrayObject, newKeys, index = false) {
    let newArray = [];
    arrayObject.forEach((obj,item)=>{
        const keyValues = Object.keys(obj).map((key,i) => {
            return {[newKeys[i] || key]:obj[key]}
        });
        let id = (index) ? {'ID':item} : {}; 
        newArray.push(Object.assign(id, ...keyValues));
    });
    return newArray;
}

测试

const obj = [{ a: "1", b: "2" }, { a: "5", b: "4" } ,{ a: "3", b: "0" }];
const newKeys = ["A","C"];
const renamedObj = renameKeys(obj, newKeys);
console.log(renamedObj);

答案 23 :(得分:0)

  • 您可以使用实用程序来处理此问题。
npm i paix
import { paix } from 'paix';

const source_object = { FirstName: "Jhon", LastName: "Doe", Ignored: true };
const replacement = { FirstName: 'first_name', LastName: 'last_name' };
const modified_object = paix(source_object, replacement);

console.log(modified_object);
// { Ignored: true, first_name: 'Jhon', last_name: 'Doe' };

答案 24 :(得分:0)

尝试使用lodash变换。

var _ = require('lodash');

obj = {
  "name": "abc",
  "add": "xyz"
};

var newObject = _.transform(obj, function(result, val, key) {

  if (key === "add") {
    result["address"] = val
  } else {
    result[key] = val
  }
});
console.log(obj);
console.log(newObject);

答案 25 :(得分:0)

const clone = (obj) => Object.assign({}, obj);

const renameKey = (object, key, newKey) => {

    const clonedObj = clone(object);
  
    const targetKey = clonedObj[key];
  
  
  
    delete clonedObj[key];
  
    clonedObj[newKey] = targetKey;
  
    return clonedObj;
     };

  let contact = {radiant: 11, dire: 22};





contact = renameKey(contact, 'radiant', 'aplha');

contact = renameKey(contact, 'dire', 'omega');



console.log(contact); // { aplha: 11, omega: 22 };

答案 26 :(得分:0)

简单地这样做会有什么问题吗?

someObject = {...someObject, [newKey]: someObject.oldKey}
delete someObject.oldKey

如果愿意,可以将其包装在函数中:

const renameObjectKey = (object, oldKey, newKey) => {
    // if keys are the same, do nothing
    if (oldKey === newKey) return;
    // if old key doesn't exist, do nothing (alternatively, throw an error)
    if (!object.oldKey) return;
    // if new key already exists on object, do nothing (again - alternatively, throw an error)
    if (object.newKey !== undefined) return;

    object = { ...object, [newKey]: object[oldKey] };
    delete object[oldKey];

    return { ...object };
};

// in use
let myObject = {
    keyOne: 'abc',
    keyTwo: 123
};

// avoids mutating original
let renamed = renameObjectKey(myObject, 'keyTwo', 'renamedKey');

console.log(myObject, renamed);
// myObject
/* {
    "keyOne": "abc",
    "keyTwo": 123,
} */

// renamed
/* {
    "keyOne": "abc",
    "renamedKey": 123,
} */

答案 27 :(得分:-1)

const data = res
const lista = []
let newElement: any

if (data && data.length > 0) {

  data.forEach(element => {
      newElement = element

      Object.entries(newElement).map(([key, value]) =>
        Object.assign(newElement, {
          [key.toLowerCase()]: value
        }, delete newElement[key], delete newElement['_id'])
      )
    lista.push(newElement)
  })
}
return lista