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