You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ramda根据嵌套属性过滤对象数组的技术方案问询

基于嵌套路径的Ramda数组过滤方案

问题背景

现有一组嵌套结构的数据,需要通过自定义条件(支持嵌套路径)过滤数组。基础实现仅支持顶层属性过滤,无法处理嵌套场景,希望找到无需预处理数据的优雅方案。

数据结构

const data = [
    { name: 'John', age: 36, color: {red: 243, green: 22, blue: 52} },
    { name: 'Jane', age: 28, color: {red: 23, green: 62, blue: 15} },
    { name: 'Lisa', age: 42, color: {red: 89, green: 10, blue: 57} }
]

过滤条件定义

每个条件包含id、filter(映射Ramda断言函数)、path(嵌套属性路径)、可选value(过滤阈值):

const definitions = [
    {
        id: 'name',
        filter: 'includes',
        path: [],
    },
    {
        id: 'age',
        filter: 'gte',
        path: [],
        value: 36
    },
    {
        id: 'red',
        filter: 'gte',
        path: ['color', 'red'],
        value: 40
    },
    {
        id: 'blue',
        filter: 'gte',
        path: ['color', 'blue']
    }
]

规则与预期结果

  • 仅当条件存在value属性时,该过滤规则生效
  • 预期过滤结果:
{
    age: 36,
    color: {
        blue: 52,
        green: 22,
        red: 243
    },
    name: "John"
}

优雅解决方案

放弃使用where,改用allPass组合针对嵌套路径的断言函数:

const Operations = {
    includes,
    equals,
    gte
};

// 生成单个过滤条件对应的断言函数
const createPredicate = (def) => {
    if (!('value' in def)) return always(true);
    const op = Operations[def.filter];
    return pipe(path(def.path), op(def.value));
};

// 组合所有断言,仅当全部条件满足时保留对象
const filterPredicate = allPass(definitions.map(createPredicate));

// 执行过滤
const result = filter(filterPredicate, data);

方案解析

  1. createPredicate:为每个条件生成独立断言:
    • 无value的条件直接返回always(true),不参与过滤
    • 用path(def.path)精准提取嵌套属性值
    • 通过pipe将属性提取与Ramda操作函数(如gte(40))组合成断言
  2. allPass:将所有断言合并为一个总条件,只有当对象满足所有生效规则时才被保留
  3. 无需修改原始数据结构,完全基于Ramda的函数式特性实现,代码简洁且可维护

内容的提问来源于stack exchange,提问作者marchello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:44:57