2016-01-09 9 views
78

У меня есть плоский объект JS:клонировать объект JS кроме одного ключа

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

Я хочу, чтобы клонировать объект для одного элемента, за исключением:

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

Что это самый простой способ сделать это (предпочитая использовать es6/7, если это возможно)?

ответ

131

Если вы используете Babel вы можете использовать следующий синтаксис для скопировать свойство б из й в переменные Ь, а затем скопировать остальные свойства в переменные у:

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

и it will be transpiled в:

"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"]); 
+8

Если вы наберете свой код для неиспользуемых переменных, это приведет к «неиспользуемой переменной» b ». предупреждение. –

+0

, как бы выглядел синтаксис, если бы у вас было 'let x = [{a: 1, b: 2, c: 3, z: 26}, {a: 5, b: 6, c: 7, z: 455}] ; ' – ke3pup

+0

вы можете использовать [Array.prototype.map()] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map) для массива. '' 'let y = x.map (item => {/ * удалить один ключ из элемента и вернуть его * /})' '' –

5

Может быть что-то вроде этого:

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

Является ли это достаточно хорошо? Или не может c действительно скопировать?

+0

Просто избитый удар. – dardub

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

или если вы принимаете свойство быть неопределенным:

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

Простое удаление объекта - это простой и понятный способ сделать это. – sshow

+4

Предостережение с удалением заключается в том, что это не неизменная операция. –

+0

это держит ключ –

12

Вы можете написать простую вспомогательную функцию для этого. Lodash имеет аналогичную функцию с тем же именем: omit

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} 

Кроме того, обратите внимание, что это быстрее, чем Object.assign и удалять потом: http://jsperf.com/omit-key

26

Чтобы добавить к ответу Ильи Палкина: вы можете даже динамически удалить ключи:

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

Источник:

+0

Элемент '[key]: deletedKey' очень хорош, потому что он работает для зарезервированных ключевых слов, например: ' let {['for']: deletedKey, ... otherKeys} = {a: 1, b: 2, for: 10} ' ' // otherKeys = {a: 1, b: 2} => no more 'for' key' Я использую его с React/JSX и TypeScript –

+0

Это хороший синтаксис. – Hinrich

+0

Это замечательно, но есть ли способ избежать неиспользованного var deletedKey? Не то, чтобы это вызывало какие-либо проблемы, но заставляет JSHint жаловаться и кажется странным, поскольку мы действительно не используем его. –

24

Для тех, кто не может использовать ES6, вы можете использовать lodash или underscore.

_.omit(x, 'b') 

or ramda.

R.omit('b', x) 
+4

не было бы логичнее использовать [omit] (https://lodash.com/docs/4.17.4#omit) здесь? '_.omit (x, 'b')' – tibalt

+0

Спасибо @tibalt. Обновлен ответ с ним. – dashmug

1

Если вы имеете дело с огромной переменной, вы не хотите, чтобы скопировать его, а затем удалить его, так как это было бы неэффективно.

Простой для контура с проверкой hasOwnProperty должен работать, и это гораздо более приспособленными к будущим потребностям:

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

Lodash omit

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

Если вы планируете использовать lodash Я предлагаю вам использовать .omit, который является простым способом создания объекта, состоящего из существующих свойств объекта, кроме тех, которые вы выбрали, проблема в том, что он описан в документации медленнее, чем .pick, поэтому вы м ay подумайте дважды, прежде чем использовать его

var object = {a: 1, b: 2, c: 3, ..., z:26}; // your object 
_.pick(object, ['b']); 
// => { 'a': 1, 'c': 3, ..., z:26 }