如何用Ramda按多条件过滤对象数组并提取ID?
如何用Ramda从对象数组中按指定条件提取ID数组
需求是从对象数组中提取满足以下任一条件的对象的id组成数组:
- 对象不包含
delete属性 - 对象包含
delete属性且其值为false
示例数组:
const array = [{id: 1, name: "test1"}, {id: 2, name: "test2", delete: true}, {id: 3, name: "test3", delete: false}]
期望结果:[1, 3]
现有代码的问题
你当前的代码逻辑存在错误:当对象包含delete属性时,pipe(propEq("delete", false), prop("id"))会先判断delete是否为false(返回布尔值),再对这个布尔值调用prop("id"),这不仅得不到正确的id,还会产生undefined无效值。
正确实现方式
Ramda的核心思路是先筛选符合条件的对象,再映射提取目标字段,逻辑更清晰直观:
const { pipe, filter, map, prop, either, complement, has, propEq } = R; const array = [{id: 1, name: "test1"}, {id: 2, name: "test2", delete: true}, {id: 3, name: "test3", delete: false}]; // 定义判断规则:满足任一条件即合法 const isValid = either( // 条件1:对象不包含delete属性 complement(has("delete")), // 条件2:对象的delete属性值为false propEq("delete", false) ); // 筛选合法对象 → 提取id数组 const result = pipe( filter(isValid), map(prop("id")) )(array); console.log(result); // [1, 3]
也可以写成更紧凑的链式调用形式:
const result = R.pipe( R.filter(R.either(R.complement(R.has('delete')), R.propEq('delete', false))), R.map(R.prop('id')) )(array);
代码说明
complement(has("delete")):对has("delete")取反,用于判断对象是否不包含delete属性;propEq("delete", false):直接校验对象的delete属性是否等于false;either(fn1, fn2):逻辑或操作,只要fn1或fn2返回true,整体就判定为合法;- 先通过
filter过滤出合法对象,再用map提取每个对象的id,最终得到目标数组。
内容的提问来源于stack exchange,提问作者mjolk
相关产品推荐
相关产品推荐

