[英]How do I refactor this code using ramda.js?
I'm using mithril.js
and ramda.js
. 我正在使用
mithril.js
和ramda.js
。 I have the following code in mithril: 我在秘银中有以下代码:
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)
]);
So basically I'm iterating over ctrl.items
and item.policies
is just an array of simple functions returning true / false
. 因此,基本上我要遍历
ctrl.items
和item.policies
只是返回true / false
的简单函数数组。 Therefore, R.allPass(item.policies)(item)
gives me either true
if everything passes or false
otherwise and then this decides whether to render li
tag or not. 因此,如果一切顺利,
R.allPass(item.policies)(item)
给出的结果为true
,否则为false
,然后由我决定是否渲染li
标签。
So instead of this functionality, I thought it would be better to create this more functional way as I will be able to reuse the code. 因此,我认为最好使用这种功能更多的方法来创建此功能,因为我将能够重用代码。 So instead of map, I thought I would
filter
down the items using that R.allPass
and then just render out the filtered array instead. 因此,我想不要使用map,而是使用
R.allPass
filter
掉项目,然后渲染出过滤后的数组。
I started fiddling around with a simple filter in ramda, but I cannot figure out how to achieve the result: 我开始在ramda中摆弄一个简单的过滤器,但是我不知道如何获得结果:
var filterItems = R.filter(
R.pipe(
R.prop('policies'),
R.allPass
)
);
This just returns the full array. 这只是返回完整的数组。 It doesn't exclude any items at all.
它根本不排除任何项目。
Well, from what I can make of your types, the issue is that you're expecting a function to do double-duty. 好吧,根据我对您的类型的理解,问题在于您期望函数执行双重任务。
Assuming items
contains a list of objects such as this: 假设
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,
]
}
];
then this: 然后这个:
R.pipe(
R.prop('policies'),
R.allPass
)
will have a type something like: 将具有类似以下内容的类型:
const testPolicies = R.pipe(
R.prop('policies'), // :: Item -> [(Item -> Boolean)]
R.allPass // :: [(Item -> Boolean)] -> Item -> Boolean
) // => :: Item -> Item -> Boolean
You need to pass two copies of your item to this function to get it to return a boolean. 您需要将项目的两个副本传递给此函数,以使其返回布尔值。 But you treat it as though it would work with just one, as though it could serve as an input to
filter :: (Item -> Boolean) -> [Item] -> [Item]
. 但是您将其视为仅适用于一个,就好像它可以用作
filter :: (Item -> Boolean) -> [Item] -> [Item]
。
You need a way to transform your (Item -> Item -> Boolean)
into a (Item -> Boolean)
. 您需要一种将
(Item -> Item -> Boolean)
转换为(Item -> Boolean)
。
There is nothing built into Ramda to help with this, although perhaps Ramda should consider adding this, as it's occasionally useful. Ramda并没有内置任何功能来帮助解决此问题,尽管Ramda可能会考虑添加此功能,因为它偶尔会有用。 But one of the standard combinators 1 , known as
W
would do this: 但是,称为
W
的标准组合器1之一将执行此操作:
const W = f => x => f(x)(x);
You could then use it like this: 然后,您可以像这样使用它:
R.filter(W(testPolicies), items); //=>
// {
// name: 'foo',
// val: 13,
// policies: [
// obj => obj.val > 10,
// obj => obj.val < 20,
// obj => obj.val % 2 == 1,
// ]
// }
You can see this in action on the Ramda REPL . 您可以在Ramda REPL上看到这一点。
1 There is a nice list of combinators in Avaq's gist . 1在Avaq的要旨中,有很多组合器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.