2015-10-10 6 views
35

Was ist ein guter und kurzer Weg, um einen Wert von einem Objekt an einem bestimmten Schlüssel zu entfernen, ohne das ursprüngliche Objekt zu mutieren?Wert aus Objekt entfernen, ohne es zu mutieren

Ich möchte etwas tun:

let o = {firstname: 'Jane', lastname: 'Doe'}; 
let o2 = doSomething(o, 'lastname'); 
console.log(o.lastname); // 'Doe' 
console.log(o2.lastname); // undefined 

Ich kenne eine Menge von Unveränderlichkeit Bibliotheken für solche Aufgaben gibt es, aber ich möchte, ohne eine Bibliothek wegzukommen. Eine Anforderung wäre jedoch eine einfache und kurze Methode, die im gesamten Code verwendet werden kann, ohne dass die Methode als Dienstprogrammfunktion abstrahiert wird.

z. Wert für das Hinzufügen muss ich folgendes:

let o2 = {...o1, age: 31};

Das ist ziemlich kurz, leicht zu merken und keine Nutzenfunktion benötigen.

Gibt es so etwas zum Entfernen eines Wertes? ES6 ist sehr willkommen.

Vielen Dank!

+0

"Wert entfernen, ohne das Objekt mutiert" keinen Sinn machen. Sie können nicht aus etwas entfernen und es gleichzeitig intakt halten. Was Sie gerade machen, ist eine Teilkopie. – JJJ

Antwort

83

Update:

Sie eine Eigenschaft von einem Objekt mit einer kniffligen Destructuring assignment entfernen konnte:

const doSomething = (obj, prop) => { 
    let {[prop]: omit, ...res} = obj 
    return res 
} 

Obwohl, wenn Eigenschaftsnamen Sie statisch entfernen möchten, dann können Sie es mit einem einfachen entfernen Einzeiler:

let {lastname, ...o2} = o 

Die einfachste Weg ist einfach zu Oder Sie könnten Ihr Objekt klonen, bevor es mutiert:

const doSomething = (obj, prop) => { 
    let res = Object.assign({}, obj) 
    delete res[prop] 
    return res 
} 

Alternativ könnten Sie omit function from lodash utility library:

let o2 = _.omit(o, 'lastname') 

Es ist erhältlich als Teil lodash Paket oder als eigenständiges lodash.omit Paket .

+2

Ist das wirklich die einfachste Lösung? Z.B. Für Arrays können Sie 'a2 = a1.filter (el => el.id! == id)' verwenden, um ein Element innerhalb eines Arrays durch eine spezifische ID auszulassen. Gibt es so etwas für ein Objekt nicht? – amann

+0

Ich stimme @amann zu. Entweder gibt es * eine bessere Lösung, oder ES6 hat wirklich etwas verpasst, JS brauchbarer zu machen. Z.B. Ruby hat ['keep_if'] (http://apidock.com/ruby/Hash/keep_if) –

+1

@AugustinRiedinger eigentlich gibt es einen Weg. Siehe mein Update. –

2

Wie in den obigen Kommentaren vorgeschlagen, wenn Sie diese erweitern möchten, um mehr als einen Artikel aus Ihrem object zu entfernen, möchte ich filter verwenden. und reduce

zB

const o = { 
 
     "firstname": "Jane", 
 
     "lastname": "Doe", 
 
     "middlename": "Kate", 
 
     "age": 23, 
 
     "_id": "599ad9f8ebe5183011f70835", 
 
     "index": 0, 
 
     "guid": "1dbb6a4e-f82d-4e32-bb4c-15ed783c70ca", 
 
     "isActive": true, 
 
     "balance": "$1,510.89", 
 
     "picture": "http://placehold.it/32x32", 
 
     "eyeColor": "green", 
 
     "registered": "2014-08-17T09:21:18 -10:00", 
 
     "tags": [ 
 
     "consequat", 
 
     "ut", 
 
     "qui", 
 
     "nulla", 
 
     "do", 
 
     "sunt", 
 
     "anim" 
 
     ] 
 
    }; 
 

 
    const removeItems = ['balance', 'picture', 'tags'] 
 
    console.log(formatObj(o, removeItems)) 
 

 
    function formatObj(obj, removeItems) { 
 
     return { 
 
     ...Object.keys(obj) 
 
      .filter(item => !isInArray(item, removeItems)) 
 
      .reduce((newObj, item) => { 
 
      return { 
 
       ...newObj, [item]: obj[item] 
 
      } 
 
      }, {}) 
 
     } 
 
    } 
 

 
    function isInArray(value, array) { 
 
     return array.indexOf(value) > -1; 
 
    }