拉姆达:哪里呢?

时间:2019-04-15 11:56:36

标签: javascript functional-programming ramda.js

我使用Ramda作为我的功能编程帮助程序库来构建React应用。

我正在尝试建立自己的whereAny。 Ramda公开了where,它检查给出的每个道具是否满足各自的谓词。

我想构建一个函数,该函数接受键数组,对象和搜索项,并且如果任何键(值为字符串)包括搜索项,它都应返回true。如果不是,则应返回false

这是我当前的解决方法:

export const whereAny = keys => obj => searchTerm =>
  R.any(
    R.pipe(
      R.toLower,
      R.includes(R.toLower(searchTerm))
    ),
    R.values(R.pick(keys, obj))
  );
export const contactNameIncludesSearchValue = whereAny(['firstName', 'lastName']);

如您所见,我用它来查看联系人的某些值是否包含搜索词(IRL,我使用的不仅仅是firstNamelastName)。

我的问题是,如何构建这样的whereAny函数?我在Ramda cookbook和Google上进行了调查,找不到whereAny的食谱。

我的解决方法存在的问题(除了可能不是最优的事实)是,您不能像where中那样指定其他函数。因此,理想情况下,我的api应该如下所示:

const pred = searchValue => R.whereAny({
  a: R.includes(searchValue),
  b: R.equals(searchValue),
  x: R.gt(R.__, 3),
  y: R.lt(R.__, 3)
});

3 个答案:

答案 0 :(得分:2)

这就是我要做的:

const fromPair = R.apply(R.objOf);

const whereFromPair = R.compose(R.where, fromPair);

const whereAny = R.compose(R.anyPass, R.map(whereFromPair), R.toPairs);

tested it就可以了。

答案 1 :(得分:2)

我认为您应该使用Ramda的curry来实现函数的功能。

为什么?

通过这种形式的欺骗,您必须以这种方式(仅限这种方式)进行调用:

const abc = a => b => c => a + b + c;
abc(1)(2)(3); // 6

与此表格相比,您更加灵活:

const abc = curry((a, b, c) => a + b + c);
abc(1, 2, 3); // 6
abc(1, 2)(3); // 6
abc(1)(2)(3); // 6

还请注意,Ramda函数倾向于接受其操作的数据作为最后一个参数:

  

Ramda函数被自动管理。这样,您只需不提供最终参数即可轻松地从旧功能中构建新功能。

     

Ramda函数的参数进行了排列,以方便进行计算。通常要最后处理要处理的数据。

     

最后两点在一起使构建函数成为更简单的函数序列变得非常容易,每个函数都会转换数据并将其传递给下一个。 Ramda旨在支持这种编码风格。

cf project homepage

我认为我们仍然可以使用这种方法来解决您的问题:

const whereAny = curry((keys, search, obj) =>
  compose(includes(search), props(keys))
    (obj));
    
const whereNameIsFoo = whereAny(['firstName', 'lastName'], 'foo');

console.log(whereNameIsFoo({firstName: 'john', lastName: 'foo'}));
console.log(whereNameIsFoo({firstName: 'bar', lastName: 'baz'}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {curry, compose, flip, includes, props} = R;</script>

答案 2 :(得分:2)

我可能会使用Aadit M Shah的答案,但您也可以在implementation of where

上对其建模

const whereAny = R.curry((spec, testObj) => {
  for (let [key, fn] of Object.entries(spec)) {
    if (fn(testObj[key])) {return true}
  }
  return false
})

const pred = searchValue => whereAny({
  a: R.includes(searchValue),
  b: R.equals(searchValue),
  x: R.gt(R.__, 3),
  y: R.lt(R.__, 3)
});

console.log(pred("hello")({ a: [], b: "hola", x: 3, y: 2 }));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>