I wonder why ramda's map-function is not behaving as I would like i.e. 'dataAllAgesAllF' is an Object of more than 5 key-value pairs and I would like to choose only those key-value pairs that match the keys of 'ageGroupData'. The list line prints out nicely the 5 correct keys and the map-line works if I write explicitly x[ageGroupFNames[0]] instead of the arrow function
const ageGroupFNames = Object.keys(ageGroupData);
const dataAllAges5F = map((x) => [ageGroupFNames.forEach((FName) => x[FName])], dataAllAgesAllF);
ageGroupFNames.forEach((FName) => console.log(FName));
ageGroupData looks like this printed to console:
{F_team_ka: 7.3671186441, F_mult_ka: 6.3776666667, F_quic_ka: 6.3113333333, F_lang_ka: 5.9703333333, F_focu_ka: 5.9276666667}
F_focu_ka: 5.9276666667
F_lang_ka: 5.9703333333
F_mult_ka: 6.3776666667
F_quic_ka: 6.3113333333
F_team_ka: 7.3671186441
__proto__: Object
Currently dataAllAges5F prints out:
0: Array(1)
0: undefined
length: 1
__proto__: Array(0)
length: 1
__proto__: Array(0)
So I would like dataAllAges5F to look exactly like ageGroupData but with different numerical values there - actually, I finally would like to combine those two to plot with Billboard.js.
You can use the R.pick()
method instead of map to return a subset of the dataAllAgesAllF
object containing all the keys from the specified array (ie: the array of keys from your ageGroupData
object):
const dataAllAges5F = pick(keys(ageGroupData), dataAllAgesAllF);
console.log(dataAllAges5F);
const ageGroupData = {F_team_ka: 7.3671186441, F_mult_ka: 6.3776666667, F_quic_ka: 6.3113333333, F_lang_ka: 5.9703333333, F_focu_ka: 5.9276666667};
const dataAllAgesAllF = {foo: 1, bar: 1, baz: 1, qux: 1, F_team_ka: 2, F_mult_ka: 3, F_quic_ka: 4, F_lang_ka: 5, F_focu_ka: 6};
const dataAllAges5F = pick(keys(ageGroupData), dataAllAgesAllF);
console.log(dataAllAges5F);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>
<script>const {keys, pick} = R;</script>
Note: If a key from ageGroupData
does not appear in dataAllAgesF
, then it won't appear in the resulting object dataAllAges5F
. If you want the key to appear and hold a value of undefined, you can use R.pickAll()
instead.
Since Ramda supports/focuses on functional-style methods, you can convert the above into a point-free function definition. The first step is to curry _.pick
arguments:
const dataAllAges5F = pick(keys(ageGroupData))(dataAllAgesAllF);
Now we can remove the last passed in argument and use a function to pass that in instead (ie: eta-reduce the function):
const pickByObj = pick(keys(ageGroupData)); // pickByObj(<object>) same as the above call
Next step is to compose the above function call. We see that the above is in the form of f(g(x))
, which can be re-written as f.g(x)
- ie: a composed function:
pick(keys(ageGroupData)); // Of the form f(g(x))
^-f ^-g ^-x
To compose functions we can use the compose
function:
const pickByObj = compose(pick, keys)(ageGroupData); // Of the form (f.g)(x)
Again, we can eta-reduce this to remove the ageGroupData
:
const pickByObj = compose(pick, keys);
Now to call the above, you can pass through your two curried argument objects:
const dataAllAges5F = pickByObj(ageGroupData)(dataAllAgesAllF);
const ageGroupData = {F_team_ka: 7.3671186441, F_mult_ka: 6.3776666667, F_quic_ka: 6.3113333333, F_lang_ka: 5.9703333333, F_focu_ka: 5.9276666667};
const dataAllAgesAllF = {foo: 1, bar: 1, baz: 1, qux: 1, F_team_ka: 2, F_mult_ka: 3, F_quic_ka: 4, F_lang_ka: 5, F_focu_ka: 6};
const pickByObj = compose(pick, keys);
console.log(pickByObj(ageGroupData)(dataAllAgesAllF));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>
<script>const {compose, pick, keys} = R;</script>