How to filter out specific keys from object using Ramda?
Solution 1
Use pick:
let newObj = R.pick(['a'], oldObj);
If your filtering criteria is more complex than just existence, you can use pickBy to select via arbitrary predicate functions.
Solution 2
The answer from Jared Smith is great. I just wanted to add a note on why your code did not work. You tried
R.filter(R.props('a'), {a: 1, b: 2, c: 3, d: 4});
First of all, you pointed to the documentation for prop
, but used props
. These are different, but related, functions. prop
looks like
// prop :: k -> {k: v} -> v
prop('c', {a: 1, b: 2, c: 3, d: 4}); //=> 3
(there is some added complexity regarding undefined
.)
props
on the other hand takes multiple values
// props :: [k] -> {k: v} -> [v]
props(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> [1, 4]
But neither of these is going to be useful input to filter
, which for these purposes we can think of as
// filter :: (k -> Bool) -> {k: v} -> {k: v}
The first parameter to filter
is a function from a (string) key to a boolean; it works with Javascript's idea that everything is truth-y except for a few specific values. It will be called with each key in turn. So for example, when deciding whether to include {c: 3}
, it calls props('a')('c')
, which for another slightly odd reason*, actually works, returning [3]
, which is treated as truth-y, and the filter function will include {c: 3}
in its output. So too every key will be included.
* The reason props('a', obj)
works when it really should be props(['a'], obj)
is that in JS, strings are close enough to lists, having a length
property and indexed values. 'a'.length; ==> 1
, 'a'[0]; //=> 'a'
. Hence props
can treat single-character strings as though they were one-element lists of character strings. But it can be a bit bizarre, too: R.props('cabby', {a: 1, b: 2, c: 3, d: 4}); //=> [3, 1, 2, 2, undefined]
.
Solution 3
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>
Leon Gaban
Investor, Powerlifter, Crypto investor and global citizen You can also find me here: @leongaban | github | panga.ventures
Updated on June 06, 2022Comments
-
Leon Gaban almost 2 years
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);
Right now the code above is returning the entire object:
newObject {"a":1,"b":2,"c":3,"d":4}
What I would like to do is just return a new object with just the
'a'
key. Or a new object with thea
andb
keys.