是否有一种巧妙(即优化)的方法来重命名javascript对象中的键?
一种非优化的方式是:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
是否有一种巧妙(即优化)的方法来重命名javascript对象中的键?
一种非优化的方式是:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
Answers:
我认为,最完整(正确)的方法是:
if (old_key !== new_key) {
Object.defineProperty(o, new_key,
Object.getOwnPropertyDescriptor(o, old_key));
delete o[old_key];
}
此方法确保重命名的属性的行为与原始属性相同。
另外,在我看来,将其包装到函数/方法中并放入其中的可能性Object.prototype
与您的问题无关。
if (old_key !== new_key)
至: if (old_key !== new_key && o[old_key])
您可以将工作包装在一个函数中,然后将其分配给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;
}
}
);
Object.defineProperty
。
hasOwnProperty
属性来检查属性和在for ... in
循环内是一种适当的做法,那么为什么扩展Object为何这么重要?
如果要更改源对象,则ES6可以一行完成。
delete Object.assign(o, {[newKey]: o[oldKey] })[oldKey];
如果要创建一个新对象,则需要两行。
const newObject = {};
delete Object.assign(newObject, o, {[newKey]: o[oldKey] })[oldKey];
[]
周围有方括号newKey
?该解决方案实际上无需解决该问题。
如果有人需要重命名属性列表:
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"}
my_object_property
为myObjectProperty
,但是,如果我的属性是单字的,那么该键将被删除。+1
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"}
如果您不想变异数据,请考虑使用此功能...
renameProp = (oldProp, newProp, {[oldProp]:old, ...others}) => ({
[newProp]: old,
...others
})
Yazeed Bzadough的详尽解释 https://medium.com/front-end-hacking/immutably-rename-object-keys-in-javascript-5f6353c7b6dd
这里的大多数答案都无法维持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] }
}
});
该解决方案通过将新条目添加到旧条目的位置来保留条目的顺序。
您可以尝试lodash _.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>
使用对象解构和散布运算符的变体:
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 the renamed properties kA, kB, kC;
// spread the remaining original properties in the 'rest' variable
const newObj = {kA, kB, kC, ...rest};
就个人而言,最有效的方法是重命名对象中的键,而无需实现额外的繁琐插件和滚轮:
var str = JSON.stringify(object);
str = str.replace(/oldKey/g, 'newKey');
str = str.replace(/oldKey2/g, 'newKey2');
object = JSON.parse(str);
try-catch
如果对象的结构无效,也可以将其包装。完美的工作:)
'a'
的{ a: 1, aa: 2, aaa: 3}
或尝试用超过字符串,数字或布尔值是什么,值重命名对象,或循环引用的尝试。
我会做这样的事情:
function renameKeys(dict, keyMap) {
return _.reduce(dict, function(newDict, val, oldKey) {
var newKey = keyMap[oldKey] || oldKey
newDict[newKey] = val
return newDict
}, {})
}
我要说的是,从概念的角度来看,最好将旧对象(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
尽管这不能为重命名提供更好的解决方案,但它提供了一种快速,简便的ES6方法,可以重命名对象中的所有键,而不会使它们包含的数据发生变异。
let b = {a: ["1"], b:["2"]};
Object.keys(b).map(id => {
b[`root_${id}`] = [...b[id]];
delete b[id];
});
console.log(b);
此页面上列出的某些解决方案有一些副作用:
这是一个将键的位置保持在同一位置并与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在严格模式下可能不支持forEach
这是我对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);
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' };