Gibt es eine clevere (d. H. Optimierte) Möglichkeit, einen Schlüssel in einem Javascript-Objekt umzubenennen?
Ein nicht optimierter Weg wäre:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
Der vollständigste (und korrekte) Weg, dies zu tun, wäre, glaube ich
if (old_key !== new_key) {
Object.defineProperty(o, new_key,
Object.getOwnPropertyDescriptor(o, old_key));
delete o[old_key];
}
Diese Methode stellt sicher, dass sich die umbenannte Eigenschaft identisch zur ursprünglichen Eigenschaft verhält.
Mir scheint auch, dass die Möglichkeit, diese Funktion in eine Funktion/Methode zu packen und sie in Object.prototype
zu packen, für Ihre Frage irrelevant ist.
Sie können die Arbeit in eine Funktion einschließen und sie dem Prototyp Object
zuordnen. Verwenden Sie möglicherweise den fließenden Schnittstellenstil, um mehrere Umbenennungen zu ermöglichen.
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-spezifisch
Ich wünschte, die Syntax wäre nicht so komplex, aber es ist definitiv schön, mehr Kontrolle zu haben.
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;
}
}
);
Wenn Sie Ihr Quellobjekt mutieren, kann ES6 dies in einer Zeile tun.
delete Object.assign(o, {[newKey]: o[oldKey] })[oldKey];
Oder zwei Zeilen, wenn Sie ein neues Objekt erstellen möchten.
const newObject = {};
delete Object.assign(newObject, o, {[newKey]: o[oldKey] })[oldKey];
Falls jemand eine Liste von Eigenschaften umbenennen muss:
function renameKeys(obj, newKeys) {
const keyValues = Object.keys(obj).map(key => {
const newKey = newKeys[key] || key;
return { [newKey]: obj[key] };
});
return Object.assign({}, ...keyValues);
}
Verwendungszweck:
const obj = { a: "1", b: "2" };
const newKeys = { a: "A", c: "C" };
const renamedObj = renameKeys(obj, newKeys);
console.log(renamedObj);
// {A:"1", b:"2"}
ES6(ES2015)
-Methode verwenden!wir müssen mit der Zeit Schritt halten!
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"}
Ich würde so etwas machen:
function renameKeys(dict, keyMap) {
return _.reduce(dict, function(newDict, val, oldKey) {
var newKey = keyMap[oldKey] || oldKey
newDict[newKey] = val
return newDict
}, {})
}
Wenn Sie Ihre Daten nicht mutieren möchten, sollten Sie diese Funktion in Betracht ziehen ...
renameProp = (oldProp, newProp, {[oldProp]:old, ...others}) => ({
[newProp]: old,
...others
})
Eine ausführliche Erklärung von Yazeed Bzadough https://medium.com/front-end-hacking/immutably-rename-object-keys-in-javascript-5f6353c7b6dd
Eine Variation mit dem Objekt-Destructuring- und Spread-Operator:
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};
Ich würde sagen, dass es aus konzeptioneller Sicht besser ist, das alte Objekt (das vom Webservice) so zu belassen, wie es ist, und die gewünschten Werte in ein neues Objekt zu packen. Ich gehe davon aus, dass Sie bestimmte Felder an einem oder anderen Punkt extrahieren, wenn nicht auf dem Client und dann auf dem Server. Die Tatsache, dass Sie sich für Feldnamen entschieden haben, die mit denen des Web-Services identisch sind (nur in Kleinbuchstaben), ändert daran nichts. Ich würde also raten, so etwas zu tun:
var myObj = {
field1: theirObj.FIELD1,
field2: theirObj.FIELD2,
(etc)
}
Natürlich mache ich hier alle möglichen Annahmen, die möglicherweise nicht zutreffen. Wenn dies nicht für Sie zutrifft, oder wenn es zu langsam ist (habe ich es nicht getestet, aber ich kann mir vorstellen, dass der Unterschied mit zunehmender Anzahl von Feldern geringer wird), ignorieren Sie bitte all dies :)
Wenn Sie dies nicht möchten und nur bestimmte Browser unterstützen müssen, können Sie die neuen Getter auch verwenden, um auch "Großbuchstaben (Feld)" zurückzugeben: siehe http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/ und die Links auf dieser Seite für weitere Informationen.
BEARBEITEN:
Unglaublich, das ist auch fast doppelt so schnell, zumindest auf meinem FF3.5 bei der Arbeit. Siehe: http://jsperf.com/spiny001
Die meisten Antworten hier können die Reihenfolge der Schlüssel-Wert-Paare von JS-Objekten nicht aufrechterhalten. Wenn Sie beispielsweise eine Form von Objektschlüssel-Wert-Paaren auf dem Bildschirm haben, die Sie ändern möchten, ist es wichtig, die Reihenfolge der Objekteinträge beizubehalten.
Die ES6-Methode zum Durchlaufen des JS-Objekts und zum Ersetzen des Schlüssel-Wert-Paares durch das neue Paar mit einem geänderten Schlüsselnamen sieht folgendermaßen aus:
let newWordsObject = {};
Object.keys(oldObject).forEach(key => {
if (key === oldKey) {
let newPair = { [newKey]: oldObject[oldKey] };
newWordsObject = { ...newWordsObject, ...newPair }
} else {
newWordsObject = { ...newWordsObject, [key]: oldObject[key] }
}
});
Die Lösung behält die Reihenfolge der Einträge bei, indem der neue Eintrag anstelle des alten Eintrags hinzugefügt wird.
Einige der auf dieser Seite aufgeführten Lösungen haben einige Nebenwirkungen:
Hier ist eine Lösung, die die Position des Schlüssels an der gleichen Stelle beibehält und in IE9 + kompatibel ist, aber ein neues Objekt erstellen muss und möglicherweise nicht die schnellste Lösung ist:
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;
}
Bitte beachten Sie: IE9 unterstützt forEach im strikten Modus möglicherweise nicht
Sie können lodash _.mapKeys
ausprobieren.
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>
Hier ein Beispiel zum Erstellen eines neuen Objekts mit umbenannten Schlüsseln.
let x = { id: "checkout", name: "git checkout", description: "checkout repository" };
let renamed = Object.entries(x).reduce((u, [n, v]) => {
u[`__${n}`] = v;
return u;
}, {});
Dies bietet zwar nicht gerade eine bessere Lösung zum Umbenennen eines Schlüssels, bietet aber eine schnelle und einfache Möglichkeit, alle Schlüssel in einem Objekt umzubenennen, ohne die darin enthaltenen Daten zu mutieren.
let b = {a: ["1"], b:["2"]};
Object.keys(b).map(id => {
b[`root_${id}`] = [...b[id]];
delete b[id];
});
console.log(b);
Dies ist eine kleine Modifikation, die ich an der Funktion von Pomber vorgenommen habe. Um ein Array von Objekten anstelle eines Objekts allein übernehmen zu können, können Sie auch den Index aktivieren. Auch die "Keys" können von einem Array zugewiesen werden
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;
}
prüfung
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);
Persönlich die effektivste Möglichkeit, Schlüssel in object umzubenennen, ohne extra schwere Plugins und Räder zu implementieren:
var str = JSON.stringify(object);
str = str.replace(/oldKey/g, 'newKey');
str = str.replace(/oldKey2/g, 'newKey2');
object = JSON.parse(str);
Sie können es auch in try-catch
einschließen, wenn Ihr Objekt eine ungültige Struktur hat. Funktioniert perfekt :)
Dein Weg ist meiner Meinung nach optimiert. Aber Sie werden mit neu geordneten Schlüsseln enden. Neu erstellte Schlüssel werden am Ende angehängt. Ich weiß, dass Sie sich niemals auf die Schlüsselreihenfolge verlassen sollten, aber wenn Sie sie beibehalten müssen, müssen Sie alle Schlüssel durchgehen und nacheinander ein neues Objekt erstellen, wobei Sie den fraglichen Schlüssel während dieses Vorgangs ersetzen müssen.
So was:
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;