简体   繁体   English

使用 Ramda 根据条件过滤对象

[英]Filtering objects based on conditions using Ramda

I want to filter out below data using Ramda .我想使用Ramda过滤掉以下数据。 The desired result is to show the properties where usage === 'Defining' .期望的结果是显示usage === 'Defining'的属性。

const data = 
[{
  "attributes":
  [
    {"usage": "Descriptive"},
    {"usage": "Defining"}
  ]
}]

So far this is what i have done and it's not filtering out data and returning the whole object.到目前为止,这就是我所做的,它没有过滤掉数据并返回整个 object。

R.filter(
 R.compose(
     R.any(R.propEq('usage', 'Defining')),
     R.prop('attributes')
  )
)(data)

Below is the desired result that i want to acheive:以下是我想要达到的预期结果:

[{
  "attributes":
  [
    {"usage": "Defining"}
  ]
}]

You are trying to do both a map and a filter here, so it's worth having separate functions for each, then composing them together to get what you want:您正在尝试在此处同时执行 map 和过滤器,因此值得为每个功能设置单独的功能,然后将它们组合在一起以获得您想要的:

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);

Ramda repl link. Ramda repl 链接。

If I understand correctly what you want to do, then where is very useful when you want to filter based on properties.如果我正确理解您想要做什么,那么当您想根据属性进行过滤时where非常有用。 But you want to combine this with map .但是您想将其与map结合使用。 While Ramda does not supply a filterMap , it's quite easy to write our own.虽然 Ramda 不提供filterMap ,但我们自己编写很容易。 We create a function that accepts a filtering function and a mapping function and returns a function which takes an array and maps only those results which pass the filter. We create a function that accepts a filtering function and a mapping function and returns a function which takes an array and maps only those results which pass the filter. Breaking the problem down that way, we could write something like:以这种方式分解问题,我们可以编写如下内容:

 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>

Obviously, there is a reasonable argument to be made for also extracting propEq ('usage', 'Defining') into a stand-alone function;显然,将propEq ('usage', 'Defining')提取到独立的 function 中也有合理的论据; that is left as an exercise for the reader.留给读者作为练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM