我可以让这个功能的防御时间更短吗?

时间:2014-10-03 11:29:12

标签: javascript functional-programming currying ramda.js

我正在尝试在我的javascript应用程序中更多地使用函数式编程。我目前使用库ramda作为基础库。

我的愿望:

  1. 创建一个函数findWithId(id, list),它返回列表中的项目,其属性_id与输入ID匹配。
  2. 尽可能缩短其实施时间,尽可能依赖现有代码。
  3. 到目前为止实现了:

    我的基础是R.find,它具有这种定位 find :: (a -> Boolean) -> [a] -> a | undefined 我尝试了下面显示的一些不同的解决方案:

    //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);
    }
    

    问题

    我可以使用标准功能编程工具(例如撰写,咖喱等)使findWithId_v2缩短为findWithId_v1吗?

    Plunker演示

    http://plnkr.co/edit/xAYx15yk6lBzutdAL9HC?p=preview

2 个答案:

答案 0 :(得分:3)

Ramda确实有一个有用的功能,一个名为useWith的功能。如果你能想到一个更好的名字,我就会喜欢它。我asked that before

你可以这样使用:

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} 

您不必提供R.identity以上。这也有用,虽然我更喜欢明确:

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

useWith"接受函数fn和任意数量的变换器函数并返回一个新函数。当调用新函数时,它调用函数fn,其参数包括在新函数的连续参数上调用每个提供的处理程序的结果"

答案 1 :(得分:0)

您正在寻找compose功能:

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)

所以你要做

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

哦,请注意您不需要hasId的函数表达式:

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