3

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

我的愿望:

  1. 创建一个函数,该函数findWithId(id, list)返回列表中具有与_id输入 id 匹配的属性的项目。
  2. 使其实现尽可能短,尽可能依赖现有代码。

迄今为止取得的成绩:

我的基础是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);
}

问题

我可以像使用标准函数式编程工具(如 compose、curry 等)findWithId_v2一样缩短吗?findWithId_v1

Plunker 演示

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

4

2 回答 2

3

Ramda 确实有一个功能可以帮助解决这个问题,一个叫做useWith. 如果你能想到一个更好的名字,我会喜欢的。我以前问过

你可以这样使用:

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,该参数由在新函数的连续参数上调用每个提供的处理程序的结果组成”

于 2014-10-03T13:28:37.397 回答
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');
于 2014-10-03T11:46:58.903 回答