我使用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,我使用的不仅仅是firstName
和lastName
)。
我的问题是,如何构建这样的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)
});
答案 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旨在支持这种编码风格。
我认为我们仍然可以使用这种方法来解决您的问题:
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>