【问题标题】:Ramda, filter with or conditionRamda,使用或条件过滤
【发布时间】:2019-10-30 07:06:06
【问题描述】:
let arr = [
  {
    name: 'Anna',
    q: {
      name: 'Jane'
    }
  }
];

const getName = R.prop('name');
const getQname = R.path(['q','name']);

这两个函数中的任何一个都通过的过滤器。

类似:

export const filterByName = (name) => 
R.filter(
  R.or(
   R.propEq(getName, name),
   R.propEq(getQname, name)
  )
)

不工作。如何在 R.filter 中组合这两个函数?

【问题讨论】:

    标签: ramda.js


    【解决方案1】:

    将 R.either 与 R.propEq 一起用于 name 和来自 q.name 的 R.pathEq:

    const filterByName = (name) =>
      R.filter(
        R.either(
          R.propEq('name', name),
          R.pathEq(['q', 'name'], name)
        )
      )
    
    const arr = [{"name":"Anna","q":{"name":"Jane"}},{"name":"Smite","q":{"name":"Jane"}},{"name":"Another","q":{"name":"One"}}];
    
    console.log(filterByName('Anna')(arr))
    console.log(filterByName('Jane')(arr))
    console.log(filterByName('XXX')(arr))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

    如果要使用外部函数来提取值,可以使用 R.pipe。使用 R.juxt 提取所有属性值,然后使用 R.any 和 R.equal 检查是否相等。

    const getName = R.prop('name');
    const getQname = R.path(['q','name']);
    
    const filterByName = (name) =>
      R.filter(
        R.pipe(
          R.juxt([getName, getQname]), // get all names
          R.any(R.equals(name)) // check if any of the equals to name
        )
      )
    
    const arr = [{"name":"Anna","q":{"name":"Jane"}},{"name":"Smite","q":{"name":"Jane"}},{"name":"Another","q":{"name":"One"}}];
    
    console.log(filterByName('Anna')(arr))
    console.log(filterByName('Jane')(arr))
    console.log(filterByName('XXX')(arr))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

    【讨论】:

    • 好收获!我没有看到 OP 原始尝试中的路径问题。我更新了我的答案,但归功于你。
    【解决方案2】:

    我会使用either,因为它适用于函数:

    export const filterByName = (name) => 
      R.filter(R.either(
       R.propEq('name', name),
       R.pathEq(['q', 'name'], name)));
    

    const nameIs = R.propEq('name');
    const qNameIs = R.pathEq(['q','name']);
    
    export const filterByName = (name) => 
      R.filter(R.either(nameIs(name), qNameIs(name)));
    

    【讨论】:

    • 如果我想使用我以前的功能怎么办。 getName 和 getQname。在我的示例中,这些很简单,但在我的代码中,我有更复杂的提取。想重用这些功能。
    • 如果我有两个以上的条件,我会使用什么函数?
    • @Joe 你可能想看看anyPass
    • 嗯,好的。谢谢。很难确切知道要使用什么功能。有这么多。
    【解决方案3】:

    你也可以写成无点风格:

    const nameIs = R.converge(R.or, [
      R.pathEq(['name']),
      R.pathEq(['q', 'name']),
    ]);
    
    const onlyAnna = R.filter(nameIs('Anna'));
    const onlyGiuseppe = R.filter(nameIs('Giuseppe'));
    
    const data = [
      { name: 'Anna', q: { name: 'Jane' } },
      { name: 'Mark', q: { name: 'Mark' } },
      { name: 'Giuseppe', q: { name: 'Hitmands' } },
    ];
    
    console.log('Anna', onlyAnna(data));
    console.log('Giuseppe', onlyGiuseppe(data));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

    【讨论】:

      猜你喜欢
      • 2021-07-15
      • 2018-11-18
      • 2015-10-20
      • 2017-02-13
      • 1970-01-01
      • 2017-03-27
      • 2017-10-14
      • 1970-01-01
      • 2014-04-19
      相关资源
      最近更新 更多