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

如何实现递归函数按嵌套属性列表关联多份JSON5文件数据

实现思路

你的现有实现存在几个核心问题:

  • 没有处理异步等待逻辑,forEach搭配async不会等待所有请求完成,函数返回时关联操作可能还没执行完
  • 强行按路径长度奇偶拆分逻辑没有必要,嵌套关联的核心逻辑是统一的:路径分段中,奇数位(从0开始数)是要关联的集合名,偶数位是关联用的匹配字段名
  • 没有处理嵌套层级下的数组/单个值的通用替换逻辑,硬编码只处理第一层路径

完整可运行代码

async function getAllData(targetObj, nestedProperties) {
  // 深拷贝原对象避免修改原始数据,不需要可以删除该行
  const result = JSON.parse(JSON.stringify(targetObj));

  // 单条路径的递归处理函数
  const processPath = async (currentObj, pathSegments, segmentIndex = 0) => {
    // 路径处理完成直接返回
    if (segmentIndex >= pathSegments.length - 1) return;

    const collectionName = pathSegments[segmentIndex];
    const matchKey = pathSegments[segmentIndex + 1];
    
    // 要处理的字段不存在就跳过
    if (currentObj[collectionName] === undefined) return;

    // 统一兼容数组和单个值两种字段格式
    const items = Array.isArray(currentObj[collectionName]) 
      ? currentObj[collectionName] 
      : [currentObj[collectionName]];

    // 批量并行查询同层级关联数据,提升性能
    const resolvedItems = await Promise.all(
      items.map(async (item) => {
        // 如果当前项已经是关联后的对象,直接取匹配字段的值
        const matchValue = typeof item === 'object' ? item[matchKey] : item;
        // 调用你的getData方法查询关联实体
        const resolved = await getData(collectionName, { [matchKey]: matchValue });
        // 递归处理下一级关联路径
        await processPath(resolved, pathSegments, segmentIndex + 2);
        return resolved;
      })
    );

    // 替换原字段,保持和原始结构一致的数组/单个值格式
    currentObj[collectionName] = Array.isArray(currentObj[collectionName]) 
      ? resolvedItems 
      : resolvedItems[0];
  };

  // 遍历所有关联路径依次处理
  for (const path of nestedProperties) {
    const segments = path.split('.');
    if (segments.length < 2) {
      console.error(`无效路径:${path}`);
      continue;
    }
    await processPath(result, segments);
  }

  return result;
}

使用示例

// 先获取主对象
const mainObj = await getData('equations', {slug: 'mass-energy-equivalence'});
// 定义关联路径
const nestedProperties = [
  'categories.slug',
  'constants.slug.units.slug',
  'magnitudes.slug',
  'units.slug',
  'variables.slug.units.slug',
  'values.units.slug'
];
// 执行关联合并
const mergedObj = await getAllData(mainObj, nestedProperties);

注意事项

  • 如果你的getData第二个参数直接接收slug值而非查询对象,把代码中调用getData的行替换为await getData(collectionName, matchValue)即可
  • 支持任意层级的嵌套关联,不需要额外修改逻辑适配路径长度

内容的提问来源于stack exchange,提问作者Derian André

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:27:03