I'm trying to do something without writing the keyword function
(i.e. creating the function using R.*
as an exercise). The goal is a function that takes two arguments, the first is a list of ids, the second is a list of objects (with an id
property). The function should return the items from the second list that have ids from the first list. Here is a small working example (with one use of function
):
var a = [ 1, 2, 3 ];
var b = [ {id: 1, b: 'Yay!' }, { id: 3, b: 'Oh yeah!' }, { id: 4, b: 'Oh noes!' } ];
var answerFunc = function (x, y) { R.pipe(R.map(R.pipe(R.unary(R.propEq('id')), R.partialRight(R.find, y))), R.filter(R.identity))(x) };
answerFunc(a, b);
// -> [ { id: 1, b: 'Yay!' }, { id: 3, b: 'Oh yeah!' } ]
I can't figure out how to "extract" the y
parameter from the middle so I can say something like:
var answerFunc = R....
Any ideas?
a
into R.flip(R.contains)
without affecting the composition with R.prop('id')
. So now I'm calling R.always(R.prop('id'))
with null
.
Basically:converge(f, a, b)(x, y) === f(a(x, y), b(x, y))
useWith(f, a, b)(x, y) === f(a(x), b(y))
So the passed in variable makes its way "deeper" into "the middle".
((a, b) => R.chain(id => R.filter(R.propEq('id', id), b), a))
@CrossEye Agreed, I do believe this was meant to be an exercise though. :)
And coming back to it, @101100, I've found another way around the (null)
-hack, much closer to my original plan. My first try was R.converge(R.compose, R.flip(R.contains), R.always(R.prop('id')))
, but that returned a 2-ary function and I didn't understand why (it should only take in a
). So I looked at the converge
source today and noticed it chooses its arity based on the highest arity from the input functions, which was 2
for R.flip(R.contains)
. So the fix was to flag it as unary
, so the complete thing becomes:
R.useWith(R.filter, R.converge(R.compose, R.unary(R.flip(R.contains)), R.always(R.prop('id'))), R.identity);
I'm not saying it's a better solution by any means (there's still a secret noop), but I did learn something new about converge
I wanted to share. :)
pipeP
so that not all functions returned a Promise
I was trying to parse xml data using cheerio/jQuery the other day and it struck me how awkward those libraries are for functional programming.
So I decided to learn top down operator precedence-parsers and applied it to parsing CSS-expressions. End result is an attempt to make a lightweight tool for reading XML/HTML in a functional style. https://github.com/algesten/zu
Now I want it to work really well with Ramda, but I'm a bit stuck on currying. I want to have zu.parents(nodes, 'div > span')
be curried as zu.parents('div > span')(nodes)
but maybe also zu.parents(nodes)('div > span')
but then that last form is not possible since i may also want zu.parents(nodes)
as a one-arg version (just parents without an expression).
Does any of you fine minds have any thoughts on that currying conundrum?
switch(req.method) {
case 'GET':
getCacheKey(cache, url).fork(
function(err) {
getDocuments(getCollection(db, collectionName)).fork(
send404(res),
sendPage(res, cache, collectionName, url)
);
},
function(value) {
console.log('sent cached value');
res.end(value);
}
);
break;
case 'POST':
// handle post req's
break;
default:
send404(res, null);
break;
}
require('zu/inverse')
would give me same API but reverse order. i would consider making the default order expr/nodes since i acknowledge i may be the odd one out with fnuc.