web-dev-qa-db-de.com

JavaScript: Objektumbenennungsschlüssel

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 ];
203
Jean Vincent

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.

144
Valeriu Paloş

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;
        }
    }
);
85
ChaosPandion

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];
31
nverba

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

Ich möchte einfach die 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"}

 demo screen shortcut

16
xgqfrms-gildata

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
  }, {})
}
4
tldr

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


4
Mulhoon

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};
3
Jeff Lowery

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

3
Spiny Norman

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.

2
afalak

Einige der auf dieser Seite aufgeführten Lösungen haben einige Nebenwirkungen:

  1. beeinflussen die Position des Schlüssels im Objekt, indem Sie ihn unten hinzufügen (wenn dies für Sie wichtig ist)
  2. würde in IE9 + nicht funktionieren (wieder, wenn es dir wichtig ist)

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

2
Jasdeep Khalsa

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>

2
Yi-Ting Liu

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;
}, {});
1
张焱伟

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);
1
Tudor Morar

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

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

0
Novitoll

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;
0
Tomas M