[英]How do I refactor this code using ramda.js?
我正在使用mithril.js
和ramda.js
。 我在秘银中有以下代码:
return m('ul.list-inline.text-center', [
ctrl.items.map(item => R.allPass(item.policies)(item) ? m('li', m('a', {
href: item.uri,
config: m.route
}, item.name)) : null)
]);
因此,基本上我要遍历ctrl.items
和item.policies
只是返回true / false
的简单函数数组。 因此,如果一切顺利, R.allPass(item.policies)(item)
给出的结果为true
,否则为false
,然后由我决定是否渲染li
标签。
因此,我认为最好使用这种功能更多的方法来创建此功能,因为我将能够重用代码。 因此,我想不要使用map,而是使用R.allPass
filter
掉项目,然后渲染出过滤后的数组。
我开始在ramda中摆弄一个简单的过滤器,但是我不知道如何获得结果:
var filterItems = R.filter(
R.pipe(
R.prop('policies'),
R.allPass
)
);
这只是返回完整的数组。 它根本不排除任何项目。
好吧,根据我对您的类型的理解,问题在于您期望函数执行双重任务。
假设items
包含这样的对象列表:
const items = [
{
name: 'foo',
val: 13,
policies: [
obj => obj.val > 10,
obj => obj.val < 20,
obj => obj.val % 2 == 1,
]
},
{
name: 'bar',
val: 14,
policies: [
obj => obj.val > 10,
obj => obj.val < 20,
obj => obj.val % 2 == 1,
]
}
];
然后这个:
R.pipe(
R.prop('policies'),
R.allPass
)
将具有类似以下内容的类型:
const testPolicies = R.pipe(
R.prop('policies'), // :: Item -> [(Item -> Boolean)]
R.allPass // :: [(Item -> Boolean)] -> Item -> Boolean
) // => :: Item -> Item -> Boolean
您需要将项目的两个副本传递给此函数,以使其返回布尔值。 但是您将其视为仅适用于一个,就好像它可以用作filter :: (Item -> Boolean) -> [Item] -> [Item]
。
您需要一种将(Item -> Item -> Boolean)
转换为(Item -> Boolean)
。
Ramda并没有内置任何功能来帮助解决此问题,尽管Ramda可能会考虑添加此功能,因为它偶尔会有用。 但是,称为W
的标准组合器1之一将执行此操作:
const W = f => x => f(x)(x);
然后,您可以像这样使用它:
R.filter(W(testPolicies), items); //=>
// {
// name: 'foo',
// val: 13,
// policies: [
// obj => obj.val > 10,
// obj => obj.val < 20,
// obj => obj.val % 2 == 1,
// ]
// }
您可以在Ramda REPL上看到这一点。
1在Avaq的要旨中,有很多组合器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.