如何使用 Ramda 从对象中过滤掉特定的键?
How to filter out specific keys from object using Ramda?
http://ramdajs.com/0.21.0/docs/#prop
var myObject = {a: 1, b: 2, c: 3, d: 4};
var newObject = R.filter(R.props('a'), myObject);
//var newObject = R.filter(R.equals(R.props('a')), myObject);
console.log('newObject', newObject);
现在上面的代码是return整个对象:
newObject
{"a":1,"b":2,"c":3,"d":4}
我想做的只是 return 一个只有 'a'
键的新对象。或者使用 a
和 b
键的新对象。
使用pick:
let newObj = R.pick(['a'], oldObj);
如果您的过滤条件比存在性更复杂,您可以通过任意谓词函数使用 pickBy 到 select。
Jared Smith 的回答很棒。我只是想添加一个注释,说明为什么您的代码不起作用。你试过
R.filter(R.props('a'), {a: 1, b: 2, c: 3, d: 4});
首先,您指向 prop
, but used props
的文档。这些是不同但相关的功能。 prop
看起来像
// prop :: k -> {k: v} -> v
prop('c', {a: 1, b: 2, c: 3, d: 4}); //=> 3
(关于 undefined
有一些额外的复杂性。)
另一方面,props
取多个值
// props :: [k] -> {k: v} -> [v]
props(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> [1, 4]
但这些都不会成为 filter
的有用输入,出于这些目的,我们可以将其视为
// filter :: (k -> Bool) -> {k: v} -> {k: v}
filter
的第一个参数是一个从(字符串)键到布尔值的函数;它符合 Javascript 的想法,即除了一些特定值外,一切都是真实的。它将依次用每个键调用。因此,例如,在决定是否包含 {c: 3}
时,它调用 props('a')('c')
,由于另一个稍微奇怪的原因 *,它实际上起作用,返回 [3]
,它被视为 truth-y,过滤器函数将在其输出中包含 {c: 3}
。因此,每个密钥也将包括在内。
* props('a', obj)
在它真正应该是 props(['a'], obj)
时起作用的原因是在 JS 中,字符串足够接近列表,有一个 length
属性 和索引值。 'a'.length; ==> 1
、'a'[0]; //=> 'a'
。因此 props
可以将单字符字符串视为字符串的单元素列表。但它也可能有点奇怪:R.props('cabby', {a: 1, b: 2, c: 3, d: 4}); //=> [3, 1, 2, 2, undefined]
.
pickBy()
const getOnlyGoods = R.pickBy((_, key) => key.includes('good'));
const onlyGoods = getOnlyGoods({
"very good": 90,
"good": 80,
"good enough": 60,
"average": 50,
"bad": 30,
"": 10,
});
console.log(onlyGoods);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
http://ramdajs.com/0.21.0/docs/#prop
var myObject = {a: 1, b: 2, c: 3, d: 4};
var newObject = R.filter(R.props('a'), myObject);
//var newObject = R.filter(R.equals(R.props('a')), myObject);
console.log('newObject', newObject);
现在上面的代码是return整个对象:
newObject
{"a":1,"b":2,"c":3,"d":4}
我想做的只是 return 一个只有 'a'
键的新对象。或者使用 a
和 b
键的新对象。
使用pick:
let newObj = R.pick(['a'], oldObj);
如果您的过滤条件比存在性更复杂,您可以通过任意谓词函数使用 pickBy 到 select。
Jared Smith 的回答很棒。我只是想添加一个注释,说明为什么您的代码不起作用。你试过
R.filter(R.props('a'), {a: 1, b: 2, c: 3, d: 4});
首先,您指向 prop
, but used props
的文档。这些是不同但相关的功能。 prop
看起来像
// prop :: k -> {k: v} -> v
prop('c', {a: 1, b: 2, c: 3, d: 4}); //=> 3
(关于 undefined
有一些额外的复杂性。)
props
取多个值
// props :: [k] -> {k: v} -> [v]
props(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> [1, 4]
但这些都不会成为 filter
的有用输入,出于这些目的,我们可以将其视为
// filter :: (k -> Bool) -> {k: v} -> {k: v}
filter
的第一个参数是一个从(字符串)键到布尔值的函数;它符合 Javascript 的想法,即除了一些特定值外,一切都是真实的。它将依次用每个键调用。因此,例如,在决定是否包含 {c: 3}
时,它调用 props('a')('c')
,由于另一个稍微奇怪的原因 *,它实际上起作用,返回 [3]
,它被视为 truth-y,过滤器函数将在其输出中包含 {c: 3}
。因此,每个密钥也将包括在内。
* props('a', obj)
在它真正应该是 props(['a'], obj)
时起作用的原因是在 JS 中,字符串足够接近列表,有一个 length
属性 和索引值。 'a'.length; ==> 1
、'a'[0]; //=> 'a'
。因此 props
可以将单字符字符串视为字符串的单元素列表。但它也可能有点奇怪:R.props('cabby', {a: 1, b: 2, c: 3, d: 4}); //=> [3, 1, 2, 2, undefined]
.
pickBy()
const getOnlyGoods = R.pickBy((_, key) => key.includes('good'));
const onlyGoods = getOnlyGoods({
"very good": 90,
"good": 80,
"good enough": 60,
"average": 50,
"bad": 30,
"": 10,
});
console.log(onlyGoods);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>