Gibt es eine clevere (dh 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 ];
Gibt es eine clevere (dh 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 ];
Antworten:
Ich glaube, der vollständigste (und korrekteste) Weg, dies zu tun, wäre:
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 mit der ursprünglichen verhält .
Außerdem scheint mir die Möglichkeit, dies in eine Funktion / Methode zu packen und Object.prototype
einzufügen, für Ihre Frage irrelevant zu sein.
if (old_key !== new_key)
zu: if (old_key !== new_key && o[old_key])
Sie können die Arbeit in eine Funktion einbinden und sie dem Object
Prototyp zuweisen . Verwenden Sie möglicherweise den fließenden Schnittstellenstil, um mehrere Umbenennungen durchzuführen.
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 auf jeden Fall 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;
}
}
);
Object.defineProperty
.
hasOwnProperty
nach Eigenschaften und innerhalb von for ... in
Schleifen zu suchen , warum ist es dann wichtig, wenn wir Object erweitern?
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];
[]
um newKey
? Die Lösung funktioniert eigentlich ohne das.
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"}
my_object_property
zu myObjectProperty
, aber wenn mein Eigentum Einzel formuliert ist, dann wurde der Schlüssel entfernt. +1
ES6(ES2015)
Weg benutzen !Wir müssen mit der Zeit gehen!
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"}
Wenn Sie Ihre Daten nicht mutieren möchten, ziehen Sie diese Funktion in Betracht ...
renameProp = (oldProp, newProp, {[oldProp]:old, ...others}) => ({
[newProp]: old,
...others
})
Eine gründliche Erklärung von Yazeed Bzadough https://medium.com/front-end-hacking/immutably-rename-object-keys-in-javascript-5f6353c7b6dd
Die meisten Antworten hier halten die Reihenfolge der Schlüssel-Wert-Paare von JS-Objekten nicht aufrecht. 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 durch einen geänderten Schlüsselnamen lautet wie folgt:
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 hinzugefügt wird.
Sie können lodash versuchen _.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>
Eine Variation unter Verwendung des Objektzerstörungs- und Spread-Operators:
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};
Persönlich der effektivste Weg, Schlüssel im Objekt 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 einschließen, try-catch
wenn Ihr Objekt eine ungültige Struktur hat. Funktioniert perfekt :)
'a'
in { a: 1, aa: 2, aaa: 3}
oder versuchen , ein Objekt mit Werten zu benennen , die nichts mehr sind als Strings oder Zahlen oder Boolesche Werte, oder versuchen , mit zirkulären Referenzen.
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
}, {})
}
Ich würde sagen, dass es aus konzeptioneller Sicht besser wäre, das alte Objekt (das des Webdienstes) so zu belassen, wie es ist, und die benötigten Werte in ein neues Objekt einzufügen. Ich gehe davon aus, dass Sie sowieso an der einen oder anderen Stelle bestimmte Felder extrahieren, wenn nicht auf dem Client, dann zumindest auf dem Server. Die Tatsache, dass Sie Feldnamen verwendet haben, die mit denen des Webdienstes identisch sind, nur in Kleinbuchstaben, ändert daran nichts. Also würde ich 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 auf Sie zutrifft oder wenn es zu langsam ist (oder? Ich habe es nicht getestet, aber ich stelle mir vor, dass der Unterschied mit zunehmender Anzahl von Feldern kleiner wird), ignorieren Sie dies alles :)
Wenn Sie dies nicht möchten und nur bestimmte Browser unterstützen müssen, können Sie mit den neuen Gettern auch "Großbuchstaben (Feld)" zurückgeben: 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
Dies bietet zwar keine bessere Lösung für das Umbenennen eines Schlüssels, bietet jedoch eine schnelle und einfache ES6-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);
Einige der auf dieser Seite aufgeführten Lösungen haben einige Nebenwirkungen:
Hier ist eine Lösung, die die Position des Schlüssels an derselben Stelle beibehält und in IE9 + kompatibel ist, jedoch 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 möglicherweise nicht jeden im strengen Modus
Ein weiterer Weg mit der leistungsstärksten REDUCE- Methode.
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);
Dies ist eine kleine Modifikation, die ich an der Funktion von Pomber vorgenommen habe. Um ein Array von Objekten anstelle eines Objekts allein nehmen zu können, können Sie auch den Index aktivieren. Auch die "Schlüssel" 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);
Ihr Weg ist meiner Meinung nach optimiert. Aber Sie werden mit neu geordneten Schlüsseln enden. Der neu erstellte Schlüssel wird am Ende angehängt. Ich weiß, dass Sie sich niemals auf die Schlüsselreihenfolge verlassen sollten, aber wenn Sie diese beibehalten müssen, müssen Sie alle Schlüssel durchgehen und nacheinander neue Objekte erstellen und dabei den betreffenden Schlüssel ersetzen.
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;
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' };