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

纯JS实现:按用户指定字段筛选未知对象属性(无第三方库)

实现支持嵌套字段(含数组)的对象属性筛选函数

需求:编写纯JavaScript函数,无需第三方库,支持指定嵌套字段路径(类似SQL SELECT语法),从任意结构的输入对象中提取对应属性,需处理嵌套数组场景。

示例数据

待筛选对象:

const responseObject = {
  name: 'John Doe',
  age: 25,
  cars: [
     {
         name: "Test car",
         brand: "Test brand",
         accessories: [
             {
                 name: "Test accessory",
                 description: "Test description",
                 code: "1234"
             },
             {
                 name: "Test accessory",
                 description: "Test description",
                 code: "12345"
             }
        ]
     },
     {
         name: "Test car 2",
         brand: "Test brand 2",
         accessories: [
             {
                 name: "Test accessory 2",
                 description: "Test description 2",
                 code: "1234"
             },
             {
                 name: "Test accessory 2",
                 description: "Test description",
                 code: "12345"
             }
        ]
     }
    ]
};

指定保留字段:

const includedFields = {
    fields: [
        "name",
        "cars.name",
        "cars.accessories.name"
    ]
};

预期输出:

const changedResponse = {
  name: 'John Doe',
  cars: [
     {
         name: "Test car",
         accessories: [
             {
                 name: "Test accessory",
             },
             {
                 name: "Test accessory",
             }
        ]
     },
     {
         name: "Test car 2",
         accessories: [
             {
                 name: "Test accessory 2"
             },
             {
                 name: "Test accessory 2"
             }
        ]
     }
    ]
};

原代码问题分析

你当前的代码存在几个关键问题:

  • 变量名错误:filter.split(".")中的filter未定义,应该是fieldPath
  • 循环逻辑错误:内层循环遍历的是fieldsFilter.length,实际应该遍历fieldPathAttributes.length
  • 路径拼接逻辑错误:currentAttributePath的赋值逻辑颠倒,导致路径拼接错误
  • 缺失数组递归处理:遇到数组时,没有遍历数组元素并递归筛选属性

完整解决方案

以下是修复并完善后的函数,核心思路是递归遍历+路径逐步构建,统一处理对象和数组的嵌套场景:

function filterResponseFields(fieldsFilter, inputObject) {
  // 初始化结果对象
  const result = {};

  // 遍历每个需要保留的字段路径
  fieldsFilter.forEach(fieldPath => {
    const pathSegments = fieldPath.split(".");
    let currentInput = inputObject;
    let currentResult = result;

    // 遍历路径的每一层
    for (let i = 0; i < pathSegments.length; i++) {
      const segment = pathSegments[i];
      const isLastSegment = i === pathSegments.length - 1;

      // 如果当前输入是数组,需要遍历每个元素递归处理
      if (Array.isArray(currentInput)) {
        const arrayResult = [];
        // 遍历数组每个元素
        currentInput.forEach(item => {
          // 递归处理单个元素,只保留当前剩余路径的字段
          const filteredItem = filterResponseFields([pathSegments.slice(i).join(".")], item);
          if (Object.keys(filteredItem).length > 0) {
            arrayResult.push(filteredItem);
          }
        });
        // 将处理后的数组挂载到结果对应位置
        currentResult[segment] = arrayResult;
        break;
      }

      // 如果当前输入是对象
      if (typeof currentInput === 'object' && currentInput !== null) {
        // 如果不是最后一段路径,确保结果中存在该层级的对象
        if (!isLastSegment) {
          if (!currentResult[segment]) {
            currentResult[segment] = {};
          }
          // 移动到下一层级的输入和结果
          currentInput = currentInput[segment];
          currentResult = currentResult[segment];
        } else {
          // 最后一段路径,直接赋值对应属性
          currentResult[segment] = currentInput[segment];
        }
      }
    }
  });

  return result;
}

// 测试调用
const filtered = filterResponseFields(includedFields.fields, responseObject);
console.log(filtered);

关键逻辑说明

  1. 路径拆分:将每个字段路径按.拆分成层级数组,方便逐层遍历
  2. 数组处理:遇到数组时,遍历每个元素并递归调用函数,只传递剩余的路径片段,确保数组内的对象也能正确筛选属性
  3. 结果构建:逐层创建结果对象的结构,确保嵌套层级与输入对象匹配,只保留指定字段
  4. 空值处理:递归处理后如果对象为空则不添加,避免生成无用的空结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:25:20