1

EDIT: I've marked this as a duplicate of Can I make this function defenition [sic] even shorter?, which is functionally identical (two puns intended) and has a good answer from one of the authors of the Ramda library.

This is a question more of academic curiosity than practical need.

I'm trying out the Ramda library, which emphasises a "point-free" style of function composition.

Suppose I have an array of objects, like

var things = [
    {id: "a", value: 234},
    {id: "b", value: 345},
    {id: "c", value: 456}
]

and I wanted a function to return the element by id (or at least, for the moment, a list matching by id). In native javascript, I can say

var byId = function(id, arr) { return arr.filter(function(o) { return o.id === id; }); };

then byId('c', things) will give me an array containing just the third item.

In Ramda, I can do this more concisely and with no reference to the data:

var byIdRam = function(id) { return R.filter(R.propEq('id', id)); }

The result is a "curried" function, so byIdRam('c')(things) gives the same result as the first version.

I sense that the remaining lambda is also unnecessary, but I don't know how to compose the function without explicit reference to the id. Does anyone know a better way to write this?

UPDATE The answer is simply

var byId = R.useWith(R.find, R.propEq('id'))

This also gives the semantics I want, where it either returns a single element or undefined. Nice!

Community
  • 1
  • 1
harpo
  • 41,820
  • 13
  • 96
  • 131
  • Do you want to create a function that could be invoked like `byId()` and return the same as `byId('c', things)`? – Seva Arkhangelskiy Dec 16 '14 at 19:29
  • @seva.rubbo, yes -- at least that is consistent with the library. However, in practice I'd probably want the element found or `null` in return. I was trying to factor that out for the sake of the question. – harpo Dec 16 '14 at 19:32

1 Answers1

0

If I get it right you need something like this:

var byIdC = function () {

    var results = things.filter(function (o) {return o.id === "c";})

    return results.length ? results[0] : null;

};

Or with your Ramda library:

var byIdC = function () {

    var results = R.filter(R.propEq("id", "c"))(things);

    return results.length ? results[0] : null;

};