我正在实现一个函数,该函数执行以下详细摘要的搜索,此示例实现适用于此功能:

// findRecord :: id → [{id: number}] → {id: number}|null
const findRecord = R.curry((id, list) => R.find(R.propEq('id', id), list));
findRecord(1, [{id: 1}]); // {id: 1}


我正在尝试使用useWithhttps://ramdajs.com/docs/#useWith)实现该方法:

// findRecord :: id → [{id: number}] → {id: number}|null
const findRecord = R.useWith(R.find, [R.propEq('id'), R.identity]);
findRecord(1, [{id: 1}]); // Error('r[u] is not a function')


我要去哪里错了?我会误解useWith的签名/用法吗?如果是这样,另一个Ramda函数会在这里为我提供更好的服务吗? (“更好”的含义同样简洁,即使是用ES5编写,但仍然可供其他程序员合理使用。)

REPL

最佳答案

您做对了。唯一的问题是您使用的REPL版本:


  https://ramdajs.com/repl/?v=0.17.1#?const%20data ...


是0.17.1,而您正在阅读的文档是最新版本0.25.0。

如果查看源代码,就会看到问题,在0.17.1中,useWith开头为:

module.exports = curry(function useWith(fn /*, transformers */) {
  var transformers = _slice(arguments, 1);
  var tlen = transformers.length;
  // ...


也就是说,transformer函数应该是初始fn之后的普通参数,例如R.useWith(R.find, R.propEq('id'), R.identity);。如果像这样使用useWith,那么在您的0.17.1 REPL版本中,它将按预期工作:

const findProject1 = R.useWith(R.find, R.propEq('id'), R.identity);
findProject1(1, [{id:1}, {id: 2}]);


输出:

{"id": 1}


但是在0.18.0及更高版本中,transformers期望在第二个参数中作为数组传递,而不是作为参数列表传递。参见the source

module.exports = _curry2(function useWith(fn, transformers) {
  return curry(_arity(transformers.length, function() {
  // ...


更改似乎源自this issue等。

因此,要么升级到Ramda的最新版本,要么通过将函数作为单个参数而不是数组传入来使用useWith。您的代码可以在0.18.0+中正常运行。

07-24 16:48