Ramda,过滤或条件

Ramda, filter with or condition

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?

中组合这两个函数

我会使用 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)));

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

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>

你也可以用点自由的方式来写:

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>