Can I make this function defenition even shorter?

I am trying move more towards functional programming in my javascript applications. I currently use the library ramda as a base lib for this.

My desire:

  1. Create a function findWithId(id, list) which returns the item in the list with the property _id matching the input id.
  2. Make the implementation of it as short as possible, relying on existing code as much as possible.

Acheived so far:

My base is R.find which has this defenition

find :: (a -> Boolean) -> [a] -> a | undefined

I tried some different solutions shown below:

  • Are 'currying' and 'composition' the same concept in Javascript?
  • Given a function pipe(foo, bar, baz)(1, 2, 3), how would you implement it to be equivalent to baz(bar(foo(1,2,3)) in javascript
  • How to convert simple average function in javascript to pointfree form using Ramda?
  • Uncurry a curried function of n parameters in javascript
  • Javascript curry - what are the practical applications?
  • Make this syntax possible: var a = add(2)(3); //5
  • //Using ramdajs (ramdajs.com)
    var hasId = R.curry(function(id, item) {
      return item._id === id
    });
    
    //This doesn't work
    var findWithId_v1 = R.find(hasId);
    
    //This works but can I make it as short as v1?
    var findWithId_v2 = function(id, list) {
      return R.find(hasId(id), list);
    }
    

    Question

    Can I make findWithId_v2 as short as findWithId_v1 by using standard functional programming tools like compose, curry etc?

    Plunker demo

  • Assigning arguments to local variables in closure
  • Variadic curried sum function
  • How to reconcile Javascript with currying and function composition
  • Make function that supports currying AND the traditional multiple parameters
  • Ramda indices in nested arrays
  • Javascript curry - what are the practical applications?
  • 2 Solutions collect form web for “Can I make this function defenition even shorter?”

    Ramda does have a function that will help with this, one called useWith. If you can think of a better name, I’d love it. I’ve asked that before.

    You can use is like this:

    var findById = R.useWith(R.find, hasId, R.identity);
    
    var find5 = findById(5);
    find5([{id:3}, {id:5}]); //=> {id:5} 
    findById(5, [{id:3}, {id:5}]); //=> {id:5} 
    

    You don’t have to supply R.identity above. This would also work, although I prefer to be explicit:

    var findById = R.useWith(R.find, hasId);
    

    useWith “accepts a function fn and any number of transformer functions and returns a new function. When the new function is invoked, it calls the function fn with parameters consisting of the result of calling each supplied handler on successive arguments to the new function”

    You’re looking for the compose function:

    compose :: (a -> b) -> (b -> c) -> (a -> c)
    hasId :: p -> (i -> Boolean)
    find :: (i -> Boolean) -> ([i] -> i | undefined)
    compose :: (p -> (i -> Boolean))
               -> ((i -> Boolean) -> ([i] -> i | undefined))
               -> (p -> ([i] -> i | undefined))
    compose find hasId :: p -> ([i] -> i | undefined)
    

    So you’d do

    var findWithId = R.compose(R.find, hasId)
    

    Oh, and notice that you don’t need a function expression for hasId either:

    var hasId = R.propEq('_id');