根据键或值过滤JavaScript对象的属性
JavaScript为数组提供了非常丰富的API,但对于对象来说却不是这样。这是可以理解的,因为可以应用于对象的方法不能与对象的属性冲突。
尽管如此,作为Object
API的一部分提供的内容非常有限,因此如果我们想要进行更复杂的操作,就必须在其基础上进行构建。其中一个用例就是根据键数组或谓词函数来过滤对象的属性。
根据键过滤对象属性
给定一个对象,我们想要根据一个键数组来过滤其属性。结果应该是一个新对象,其中只包含键包含在数组中的属性。
为了实现这一点,我们将利用Object.entries()
来获取对象的键值对数组,然后使用Array.prototype.filter()
根据提供的数组来过滤键值对。最后,使用Object.fromEntries()
我们可以将过滤后的键值对转换回对象。
我们还可以实现反向操作,即过滤掉键包含在数组中的属性。只需在Array.prototype.filter()
回调中否定条件即可。
const pick = (obj, arr) =>
Object.fromEntries(Object.entries(obj).filter(([k]) => arr.includes(k)));
const omit = (obj, arr) =>
Object.fromEntries(Object.entries(obj).filter(([k]) => !arr.includes(k)));
const obj = { a: 1, b: '2', c: 3 };
## 根据键值选择对象属性
如果我们想根据给定的键数组选择对象的属性,可以使用`pick`函数。例如,我们可以选择对象`obj`中的键为`'a'`和`'c'`的属性。
```js
const pick = (obj, keys) =>
keys.reduce((acc, key) => {
if (obj.hasOwnProperty(key)) {
acc[key] = obj[key];
}
return acc;
}, {});
const omit = (obj, keys) =>
Object.keys(obj).reduce((acc, key) => {
if (!keys.includes(key)) {
acc[key] = obj[key];
}
return acc;
}, {});
const obj = { a: 1, b: '2', c: 3 };
pick(obj, ['a', 'c']); // { 'a': 1, 'c': 3 }
omit(obj, ['b']); // { 'a': 1, 'c': 3 }
有条件地过滤对象属性
前面的代码片段涵盖了大多数简单的用例,但是如果我们想根据一个谓词函数来过滤对象的属性呢?例如,我们可能想过滤掉所有值为数字的属性。
这也不是特别难实现。我们只需将数组包含检查替换为对提供的谓词函数的调用。为了使我们的函数的API更加用户友好,谓词函数应该将值作为第一个参数,将键作为第二个参数。
const pickBy = (obj, fn) =>
Object.fromEntries(Object.entries(obj).filter(([k, v]) => fn(v, k)));
const omitBy = (obj, fn) =>
Object.fromEntries(Object.entries(obj).filter(([k, v]) => !fn(v, k)));
const obj = { a: 1, b: '2', c: 3 };
pickBy(obj, x => typeof x === 'number'); // { a: 1, c: 3 }
omitBy(obj, x => typeof x !== 'number'); // { a: 1, c: 3 }