У меня есть плоский объект JS:
{a: 1, b: 2, c: 3, ..., z:26}
Я хочу клонировать объект, кроме одного элемента:
{a: 1, c: 3, ..., z:26}
Как это сделать проще всего (если возможно, предпочитая использовать es6 / 7)?
У меня есть плоский объект JS:
{a: 1, b: 2, c: 3, ..., z:26}
Я хочу клонировать объект, кроме одного элемента:
{a: 1, c: 3, ..., z:26}
Как это сделать проще всего (если возможно, предпочитая использовать es6 / 7)?
Если вы используете Babel, вы можете использовать следующий синтаксис, чтобы скопировать свойство b из x в переменную b, а затем скопировать остаток свойств в переменную y:
let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;
и он будет перенесен в:
"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"]);
let x = [{a: 1, b: 2, c: 3, z:26}, {a: 5, b: 6, c: 7, z:455}];
- person ke3pup; 09.09.2016
let y = x.map(item => { /* remove one key from the item and return it */ })
- person Ilya Palkin; 09.09.2016
ignoreRestSiblings
(3 февраля 2017 г.). См. совершить c59a0ba
- person Ilya Palkin; 07.03.2017
b
.
- person Ross Allen; 07.03.2017
x
содержит свойство объекта, и поскольку объект является ссылкой (codeburst.io/), вы можете по ошибке измените вложенное значение внутри x
при изменении его в y
.
- person papillon; 19.02.2019
bName
- это имя ключа темы - это не работает: let {[bName], ...y} = x;
Я удаляю узел прямо сейчас, он не может делать то, что мы хотим !!!! 1111 (это была одна строка, одна функция)
- person xakepp35; 09.09.2019
let y = {...x}; delete y.b;
- person jWang1; 30.03.2020
let { b: _b, ...y } = x;
, чтобы пропустить предупреждение о неиспользуемой переменной.
- person Waseem; 20.05.2021
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});
Я использую этот лайнер ESNext
const obj = { a: 1, b: 2, c: 3, d: 4 }
const clone = (({ b, c, ...o }) => o)(obj) // remove b and c
console.log(clone)
map
вы можете: (({b, c, ...others}) => ({...others}))(obj)
- person bucabay; 22.12.2018
_.omit(obj, ['b', 'c'])
.
- person totymedli; 23.09.2019
eval
?
- person Haroen Viaene; 31.01.2020
omit({}, "}));alert('gotcha!')(({a")
- person Brook Jordan; 21.07.2020
eval
в некоторых случаях не рекомендуется, я не хочу вводить в заблуждение новичков в его использовании.
- person vdegenne; 17.04.2021
Чтобы добавить к ответу Ильи Палкина: вы даже можете динамически удалять ключи:
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};
Источник:
_
, которое разрешено для переменной, которую вы не собираетесь использовать?
- person Ryan H.; 26.08.2017
Для тех, кто не может использовать ES6, вы можете использовать lodash
или underscore
.
_.omit(x, 'b')
Or ramda
.
R.omit('b', x)
delete
.
- person jimmont; 19.09.2018
Вы можете написать для него простую вспомогательную функцию. В Lodash есть аналогичная функция с тем же именем: опустить
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 < / а>
Object.keys(obj).filter(key => key != omitKey).reduce((result, key) => ({...result, [key]: obj[key]}), {});
- person wensveen; 25.09.2020
Может быть, примерно так:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
Достаточно ли этого? Или действительно c
невозможно скопировать?
Вот вариант исключения динамических ключей, который, как мне кажется, еще не упоминался:
const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;
const { [removeMe]: removedKey, ...newObj } = obj;
removeMe
имеет псевдоним removedKey
и игнорируется. newObj
становится { 2: 2, 3: 3, 4: 4 }
. Обратите внимание, что удаленный ключ не существует, значение не было просто установлено равным undefined
.
Использование деструктуризации объектов
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}
_
не решает проблему для ESLint ...
- person bert bruynooghe; 06.06.2019
Как насчет этого:
let clone = Object.assign({}, value);
delete clone.unwantedKey;
Эй, похоже, вы сталкиваетесь со ссылками на проблемы, когда пытаетесь скопировать объект, а затем удаляете свойство. Где-то вам нужно назначить примитивные переменные, чтобы javascript создавал новое значение.
Простой трюк (может быть ужасным), который я использовал, был
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"}
JSON.parse(JSON.stringify(Object.assign({}, obj, { key2: undefined })));
. Его даже не нужно удалять, просто нужно ложное значение.
- person Chad; 24.08.2018
Недавно я сделал это очень простым способом:
const obj = {a: 1, b: 2, ..., z:26};
просто используя оператор распространения, чтобы отделить нежелательное свойство:
const {b, ...rest} = obj;
... и object.assign, чтобы взять только "остальную" часть:
const newObj = Object.assign({}, {...rest});
rest
уже является новым объектом - последняя строка вам не нужна. К тому же это идентично принятому решению.
- person carpiediem; 08.05.2019
Вы также можете использовать оператор распространения, чтобы сделать это
const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
copy
- person kano; 22.09.2018
const copy = { ...source, b: undefined }
сводится к тому же самому.
- person bert bruynooghe; 06.06.2019
Object.keys(copy)
все равно вернет ['a', 'b', 'c', 'z']
, что не всегда то, что вам нужно.
- person kernel; 20.05.2021
Приведенные выше решения с использованием структурирования страдают от того, что у вас есть используемая переменная, что может вызвать жалобы со стороны ESLint, если вы ее используете.
Итак, вот мои решения:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
На большинстве платформ (кроме IE, если не используется Babel) вы также можете:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
Если вы имеете дело с огромной переменной, вы не хотите копировать ее, а затем удалять, так как это было бы неэффективно.
Простой цикл for с проверкой hasOwnProperty должен работать, и он гораздо более адаптируется к будущим потребностям:
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
Lodash опустить
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
Как насчет этого? Я никогда не встречал этого паттерна, но я просто пытался исключить одно или несколько свойств без необходимости создания дополнительного объекта. Кажется, это работает, но есть некоторые побочные эффекты, которые я не вижу. Наверняка не очень читается.
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
Я сделал это так, как пример из моего редуктора Redux:
const clone = { ...state };
delete clone[action.id];
return clone;
Другими словами:
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
const { [removeMe]: removedKey, ...newObj } = obj;
- см. Мой ответ на этот вопрос.
- person goldins; 02.10.2019
Я не знаю точно, для чего вы хотите это использовать, поэтому я не уверен, сработает ли это для вас, но я просто сделал следующее, и это сработало для моего варианта использования:
const newObj ={...obj, [key]: undefined}
У меня был object
, который я хотел удалить после использования его метода. Это то, что сработало для меня.
/* Sample data */
let items = [
{
name: 'John',
doc: {
set: async (item) => {/*...sets docs on remote server*/}
}
},{
name: 'Mary',
doc: {
set: async (item) => {/*...sets docs on remote server*/}
}
},{
name: 'Jack',
doc: {
set: async (item) => {/*...sets docs on remote server*/}
}
}
]
/* mapping to promises */
const promises = items.map(({doc, ...item}) => doc.set(item));
// utilized doc and utilized `rest` of the items :)
Удачи :)
Вот мои два цента на Typescript, немного заимствованные из ответа @Pol и использующие вместо этого reduce.
function objectWithoutKey(object: object, keys: string[]) {
return keys.reduce((previousValue, currentValue) => {
// @ts-ignore
const {[currentValue]: undefined, ...clean} = previousValue;
return clean
}, object)
}
// usage
console.log(objectWithoutKey({a: 1, b: 2, c: 3}, ['a', 'b']))
У меня есть один объект с именем: options с некоторыми ключами
let options = {
userDn: 'somePropertyValue',
username: 'someValue',
userSearchBase: 'someValue',
usernameAttribute: 'uid',
userPassword: 'someValue'
}
Я хочу зарегистрировать все свойство объекта excelp userPassword, потому что я что-то тестирую, я использую этот код:
console.log(Object.keys(options).map(x => x + ': ' + (x === "userPassword" ? '---' : options[x])));
Если вы хотите сделать его динамическим, просто создайте функцию и вместо явного указания userPassword вы можете поместить значение свойства, которое вы хотите исключить.
Решение с ключевым словом delete выдаст ошибку компиляции, если вы используете машинописный текст, потому что оно нарушает контракт объекта, который вы создали. И решение оператора распространения ES6 (const {x, ...keys} = object
) может вызывать ошибку в зависимости от конфигурации линтинга, которую вы используете в своем проекте, поскольку переменная x
не используется. Итак, я пришел к следующему решению:
const cloneObject = Object.entries(originalObject)
.filter(entry => entry[0] !== 'keyToRemove')
.reduce((acc, keyValueTuple) => ({ ...acc, [keyValueTuple[0]]: keyValueTuple[1] }), {});
Он решает проблему с помощью комбинации Object. Entries (для получения массива пар ключ / значение исходного объекта) и методы массива filter и уменьшить. Это выглядит многословно, но я думаю, что неплохо иметь решение с цепочкой в одну строку.
Используя функцию loadash deepclone, вы можете:
const _obj = _.cloneDeep(obj);
delete _obj.key;
Сначала клонирует весь объект в новый объект, а затем удаляет желаемый ключ из клонированного объекта, чтобы не повлиять на исходный.
JSON.parse
иJSON.stringify
для клонирования, но требует ES2018 ... - person FZs   schedule 27.12.2020