wake-up-neo.net

Klonen eines js-Objekts mit Ausnahme eines Schlüssels

Ich habe ein flaches JS-Objekt:

{a: 1, b: 2, c: 3, ..., z:26}

Ich möchte das Objekt mit Ausnahme eines Elements klonen:

{a: 1, c: 3, ..., z:26}

Was ist der einfachste Weg, dies zu tun (wenn möglich, bevorzuge es6/7)?

207
fox

Wenn Sie Babel verwenden, können Sie die folgende Syntax verwenden, um die Eigenschaft b von x in die Variable b zu kopieren und dann die restlichen Eigenschaften in die Variable y zu kopieren:

let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;

und es wird transpiliert in:

"use strict";

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

var x = { a: 1, b: 2, c: 3, z: 26 };
var b = x.b;

var y = _objectWithoutProperties(x, ["b"]);
310
Ilya Palkin
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;

oder wenn Sie eine Eigenschaft akzeptieren, die nicht definiert ist:

var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
109
madox2

Hinzufügen zu Ilya Palkins Antwort: Sie können Schlüssel sogar dynamisch entfernen:

const x = {a: 1, b: 2, c: 3, z:26};

const objectWithoutKey = (object, key) => {
  const {[key]: deletedKey, ...otherKeys} = object;
  return otherKeys;
}

console.log(objectWithoutKey(x, 'b')); // {a: 1, c: 3, z:26}
console.log(x); // {a: 1, b: 2, c: 3, z:26};

Demo in Babel REPL

Quelle:

55
Paul Kögel

Für diejenigen, die ES6 nicht verwenden können, können Sie lodash oder underscore verwenden.

_.omit(x, 'b')

Oder ramda.

R.omit('b', x)
53
dashmug

Ich benutze diese einzeilige ES6-Syntax,

const obj = {a: 1, b: 2, c: 3, d: 4};
const clone = (({b, c, ...others}) => ({...others}))(obj); // remove b and c
console.log(clone);
25
vdegenne

Sie können eine einfache Hilfsfunktion dafür schreiben. Lodash hat eine ähnliche Funktion mit dem gleichen Namen: weglassen

function omit(obj, omitKey) {
  return Object.keys(obj).reduce((result, key) => {
    if(key !== omitKey) {
       result[key] = obj[key];
    }
    return result;
  }, {});
}

omit({a: 1, b: 2, c: 3}, 'c')  // {a: 1, b: 2}

Beachten Sie auch, dass dies schneller ist als Object.assign und löschen Sie dann: http://jsperf.com/omit-key

20
just-boris

Vielleicht so etwas:

var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;

Ist das gut genug Oder kann c nicht tatsächlich kopiert werden?

9
clean_coding

Objektdestrukturierung verwenden

const omit = (prop, { [prop]: _, ...rest }) => rest;
const obj = { a: 1, b: 2, c: 3 };
const objWithoutA = omit('a', obj);
console.log(objWithoutA); // {b: 2, c: 3}
6
Ivan Nosov

Hey, es sieht so aus, als würden Sie auf Probleme stoßen, wenn Sie versuchen, ein Objekt zu kopieren und dann eine Eigenschaft zu löschen. Irgendwo müssen Sie primitive Variablen zuweisen, damit Javascript einen neuen Wert erhält.

Ein einfacher Trick (kann horrend sein), den ich verwendet habe, war dieser

var obj = {"key1":"value1","key2":"value2","key3":"value3"};

// assign it as a new variable for javascript to cache
var copy = JSON.stringify(obj);
// reconstitute as an object
copy = JSON.parse(copy);
// now you can safely run delete on the copy with completely new values
delete copy.key2

console.log(obj)
// output: {key1: "value1", key2: "value2", key3: "value3"}
console.log(copy)
// output: {key1: "value1", key3: "value3"}
6
Chris Fust

Lodash weglassen

let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
4
OscarRyz

Was ist damit? Ich habe dieses Muster nie gefunden, aber ich habe nur versucht, eine oder mehrere Eigenschaften auszuschließen, ohne ein zusätzliches Objekt erstellen zu müssen. Dies scheint den Job zu machen, aber es gibt einige Nebenwirkungen, die ich nicht sehen kann. Sicher ist nicht sehr gut lesbar.

const postData = {
   token: 'secret-token',
   publicKey: 'public is safe',
   somethingElse: true,
};

const a = {
   ...(({token, ...rest} = postData) => (rest))(),
}

/**
a: {
   publicKey: 'public is safe',
   somethingElse: true,
}
*/
2
andreasonny83

Wenn Sie es mit einer großen Variablen zu tun haben, möchten Sie diese nicht kopieren und anschließend löschen, da dies ineffizient wäre.

Eine einfache for-Schleife mit einer hasOwnProperty-Prüfung sollte funktionieren und ist viel anpassungsfähiger für zukünftige Anforderungen:

for(var key in someObject) {
        if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
                copyOfObject[key] = someObject[key];
        }
}
2
HoldOffHunger

Sie können dazu auch den Spread-Operator verwenden

const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
2
Mickael M.

Die oben genannten Lösungen für die Strukturierung leiden unter der Tatsache, dass Sie eine verwendete Variable haben, die möglicherweise Beschwerden von ESLint hervorruft, wenn Sie diese verwenden.

Also hier sind meine Lösungen:

const src = { a: 1, b: 2 }
const result = Object.keys(src)
  .reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})

Auf den meisten Plattformen (mit Ausnahme von IE, sofern Babel nicht verwendet wird) können Sie auch Folgendes tun:

const src = { a: 1, b: 2 }
const result = Object.fromEntries(
  Object.entries(src).filter(k => k !== 'b'))
2
bert bruynooghe

Ich habe es kürzlich ganz einfach gemacht:

const obj = {a: 1, b: 2, ..., z:26};

verwenden Sie einfach Spread-Operator, um die unerwünschte Eigenschaft zu trennen:

const {b, ...rest} = obj;

... und object.assign um nur den 'Rest'-Teil zu übernehmen:

const newObj = Object.assign({}, {...rest});
2
Pepdbm 7

Ich habe das am Beispiel meines Redux-Reduzierers so gemacht:

 const clone = { ...state };
 delete clone[action.id];
 return clone;

Mit anderen Worten:

const clone = { ...originalObject } // note: original object is not altered
delete clone[unwantedKey]           // or use clone.unwantedKey or any other applicable syntax
return clone                        // the original object without the unwanted key
1
Jonathan Tuzman

Dies sollte es auch tun; Ich bin mir ziemlich sicher, dass 'delete' auch mit assoziativen Arrays funktioniert:

var copy = (obj, del)=>{
    delete obj.del;
    return obj;
}
0
Raphael Spoerri