拉姆达:在哪里?

问题描述 投票:2回答:3

我正在使用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和谷歌,找不到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)
});
javascript functional-programming ramda.js
3个回答
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,它的工作原理。


2
投票

我认为你应该使用Ramda的curry来理解你的功能。

为什么?

使用这种形式的currying,你必须以这种方式调用它,只有这样:

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功能自动curry。这使您可以通过不提供最终参数轻松地从旧功能构建新功能。

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
投票

我可能会使用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>
© www.soinside.com 2019 - 2024. All rights reserved.