【发布时间】:2017-08-18 02:44:52
【问题描述】:
有没有一种干净的方法来返回一个新对象,它省略了原始对象包含的某些属性,而不必使用像 lodash 这样的东西?
【问题讨论】:
-
代码?我建议创建一个新的匿名类型,传入你想要保留的内容
-
这里问了一个类似的问题stackoverflow.com/questions/34698905/…
有没有一种干净的方法来返回一个新对象,它省略了原始对象包含的某些属性,而不必使用像 lodash 这样的东西?
【问题讨论】:
如果您知道希望保留和省略的属性列表,则以下“白名单”方法应该有效:
const exampleFilter = ({ keepMe, keepMeToo }) => ({ keepMe, keepMeToo })
console.log(
exampleFilter({
keepMe: 'keepMe',
keepMeToo: 'keepMeToo',
omitMe: 'omitMe',
omitMeToo: 'omitMeToo'
})
)
【讨论】:
{ keepMe, keepMeToo }就像{ keepMe: keepMe, keepMeToo: keepMeToo }。
可以使用Object.assign(),删除
var not = ["a", "b"]; // properties to delete from obj object
var o = Object.assign({}, obj);
for (let n of not) delete o[n];
或者
var props = ["c", "d"];
let o = Object.assign({}, ...props.map(prop => ({[prop]:obj[prop]})));
【讨论】:
function omitKeys(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 original = {
name: 'Rory',
state: 'Bored',
age: '27'
};
var copied = Object.assign({}, original);
delete copied.age;
console.log(copied);
【讨论】:
一个解决方案,我相信还有很多其他解决方案。
const testObj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
};
const removeProps = (...propsToFilter) => obj => {
return Object.keys(obj)
.filter(key => !propsToFilter.includes(key))
.reduce((newObj, key) => {
newObj[key] = obj[key];
return newObj;
}, {});
};
console.log(removeProps('prop3')(testObj));
console.log(removeProps('prop1', 'prop2')(testObj));
编辑:我总是忘记delete...
const testObj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
};
const removeProps = (...propsToFilter) => obj => {
const newObj = Object.assign({}, obj);
propsToFilter.forEach(key => delete newObj[key]);
return newObj;
};
console.log(removeProps('prop3')(testObj));
console.log(removeProps('prop1', 'prop2')(testObj));
【讨论】:
npm 上有 blacklist 包,它有一个非常灵活的 api。
也是使用对象剩余扩展提议(阶段 3)的情景技巧。
const {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4};
a // 1
b // 2
rest // {c: 3, d: 4}
这通常用在你想要使用一些属性并将其余的作为 props 传递给 <div {...props} /> 或类似的反应组件中。
【讨论】:
var obj = {
a: 1,
b: 2,
c: 3,
d: {
c: 3,
e: 5
}
};
Object.extract = function(obj, keys, exclude) {
var clone = Object.assign({}, obj);
if (keys && (keys instanceof Array)) {
for (var k in clone) {
var hasKey = keys.indexOf(k) >= 0;
if ((!hasKey && !exclude) || (hasKey && exclude)) {
delete clone[k];
}
}
}
return clone;
};
console.log('Extract specified keys: \n-----------------------');
var clone1 = Object.extract(obj, ['a', 'd']);
console.log(clone1);
console.log('Exclude specified keys: \n-----------------------');
var clone2 = Object.extract(obj, ['a', 'd'], true);
console.log(clone2);
【讨论】:
const { bar, baz, ...qux } = foo
现在您的对象qux 具有foo 的所有属性,除了bar 和baz。
【讨论】:
qux 将更新 foo 中的值。 Javascript 对象通过引用传递。
qux 中的值,则foo 的值将不会更新。但是,如果qux 的属性值是一个对象,并且您更改了该对象中的某些内容,那么foo 的相应属性所引用的对象也将被更改。
const { "bar", 'baz', ...qux } = foo
const x = "Anything"; const obj = { x: "Foo", y:"Bar"}; const {x, ...no_x} = obj;
如果你已经在使用 lodash,你也可以使用omit(obj, ["properties", "to", "omit"]) 来获取一个没有数组中提供的属性的新对象。
【讨论】:
在现代环境中,您可以使用此代码 sn-p:
function omit(key, obj) {
const { [key]: omitted, ...rest } = obj;
return rest;
}
【讨论】:
const {omittedPropertyA, omittedPropertyB, ...remainingObject} = originalObject;
使用 ES7
你可以使用 object destructuring 和 spread operator 来省略 javascript 对象的属性:
const animalObject = { 'bear': 1, 'snake': '2', 'cow': 3 };
const {bear, ...other} = animalObject
// other is: { 'snake': '2', 'cow:' 3}
来源:https://remotedevdaily.com/two-ways-to-omit-properties-from-a-javascript-object/
【讨论】:
const {bear, ...other} =中使用变量而不是bear
const fieldName = 'bear'; const {[fieldName]: _, ...other} = animalObject
使用带有递归的 ES7 省略和数组键。
function omit(keys, obj) {
if (!keys.length) return obj
const { [keys.pop()]: omitted, ...rest } = obj;
return omit(keys, rest);
}
这建立在@Eddie Cooro 的回答之上。
【讨论】:
export function omitObjectKeys<T extends object = {}>( keys: string[], obj: T, ): Partial<T> { return (keys as any).reduce((a: Partial<T>, e: keyof T) => { const { [e]: omitted, ...rest } = a; return rest; }, obj); }
const x = {obj1: 1, obj2: 3, obj3:26};
const {obj1,obj2, ...rest} = x;
console.log(rest)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>
【讨论】:
我看到了这个问题,我想删除 1 个特定的键,而不是完整的方法,所以这是我的建议:
const originalObj = {wantedKey: 111, anotherWantedKey: 222, unwantedKey: 1010};
const cleanedObj = Object.assign(originalObj, {unwantedKey: undefined});
【讨论】:
尚未提及的解决方案:
o = {a: 5, b: 6, c: 7}
Object.fromEntries(Object.entries(o).filter(e => e[0] != 'b'))
// Object { a: 5, c: 7 }
o = {a: 1, b: 2, c: 3, d: 4}
exclude = new Set(['a', 'b'])
Object.fromEntries(Object.entries(o).filter(e => !exclude.has(e[0])))
// Object { c: 3, d: 4 }
使用上面的Set 是因为它会导致线性复杂度,即使exclude 中的元素数与o 中的元素数属于同一渐近等价类。
【讨论】:
exclude = ['a', 'b'] 和Object.fromEntries(Object.entries(o).filter(e => !exclude.includes(e[0]))) 创建一个集合就足够了(除了令人困惑的诅咒exclude.includes :D)。
export const omit = (obj, keys) => {
const output=[];
for(const [key, value] of Object.entries(obj)){
if(!keys.includes(key)){
output.push([key,value]);
}
}
return Object.fromEntries(output);
}
【讨论】: