我想使用 Ramda 过滤出以下数据。理想的结果是显示usage === 'Defining'
所在的属性。
const data =
[{
"attributes":
[
{"usage": "Descriptive"},
{"usage": "Defining"}
]
}]
到目前为止,这是我所做的,并且还没有过滤出数据并返回整个对象。
R.filter(
R.compose(
R.any(R.propEq('usage', 'Defining')),
R.prop('attributes')
)
)(data)
以下是我要达到的理想结果:
[{
"attributes":
[
{"usage": "Defining"}
]
}]
答案 0 :(得分:1)
您正在尝试在此处同时创建地图和过滤器,因此值得为每个函数分别设置功能,然后将它们组合在一起以获得所需的内容:
const data =
[{
"attributes":
[
{"usage": "Descriptive"},
{"usage": "Defining"}
]
},
{
"attributes":
[
{"usage": "Descriptive"},
{"usage": "Definingx"}
]
}]
const removeObjectsWithoutDefining = filter(
compose(any(equals('Defining')), map(prop('usage')), prop('attributes'))
);
const adjustProp = curry((f, k, o) => ({
...o,
[k]: f(o[k]),
}));
const mapAttributesToRemoveNonDefining = map(
adjustProp(
filter(propEq('usage', 'Defining')),
'attributes',
),
)
const f = compose(mapAttributesToRemoveNonDefining, removeObjectsWithoutDefining);
f(data);
答案 1 :(得分:1)
如果我正确理解了您想做什么,那么where
在您要基于属性进行过滤时非常有用。但是您想将此与map
结合使用。尽管Ramda不提供filterMap
,但是编写我们自己的代码很容易。我们创建一个函数,该函数接受一个过滤函数和一个映射函数,并返回一个函数,该函数接受一个数组并仅映射那些通过过滤器的结果。以这种方式解决问题,我们可以编写如下内容:
const filterMap = (f, m) => (xs) =>
chain ((x) => f (x) ? [m (x)] : [], xs)
const definingProps = filterMap (
where ({attributes: any (propEq ('usage', 'Defining'))}),
over (lensProp('attributes'), filter (propEq ('usage', 'Defining')))
)
const data = [
{id: 1, attributes: [{usage: "Descriptive"}, {usage: "Defining"}]},
{id: 2, attributes: [{usage: "Descriptive"}, {usage: "Something Else"}]},
{id: 3, attributes: [{usage: "Defining"}, {usage: "Filtering"}]}
]
console .log (definingProps (data))
.as-console-wrapper {min-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {curry, chain, where, any, propEq, over, lensProp, filter} = R </script>
很显然,有一个合理的论点也可以将propEq ('usage', 'Defining')
提取到独立函数中;留给读者练习。