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

如何将嵌套数组对象转换为指定键名及驼峰格式?

解决嵌套数组对象的键转换问题:指定键替换+SnakeCase转CamelCase

问题需求

将数组中的对象转换为新对象,需满足:

  • 特定旧键替换为指定新键(如org_id替换为clientDivisionOrganizationId);
  • 其余SnakeCase格式的键自动转换为CamelCase格式;
  • 支持任意层级的嵌套对象和数组转换(如示例中addresses下的usage_types、address_usages下的嵌套address对象)。

原代码的不足

原转换逻辑仅处理了一层嵌套的对象和数组,无法递归处理更深层级的结构,导致深层嵌套的键(如address_1、usage_types)未按规则转换,且键映射的匹配逻辑不够直观。

改进方案

通过递归函数统一处理所有层级的对象和数组,确保每一层的键都应用转换规则:

  1. 调整键映射表newKeyMap,直接用原SnakeCase键作为映射键,便于匹配;
  2. 编写递归转换函数,对每个值的类型做判断:
    • 若为非数组、非null的对象:遍历键值对,转换键后递归处理值;
    • 若为数组:遍历数组元素,对每个元素递归调用转换函数;
    • 若为基本类型:直接保留值。

改进后的代码

const originalArray = [{
    "uuid": "65a49008-3291ba-4dc6-8fd8-476c4ea7b84d",
    "name": "Post-man Hospital-local",
    "site_number": "PKKk-2219232",
    "phone": "",
    "fax": "",
    "org_id": "PKKKK-2219232",
    "principal_investigator_user_uuid": null,
    "study_uuid": "863080a12c-5335-472334-9103-50ea782da3c9",
    "principal_investigator": {
        "uuid": null,
        "email": null,
        "first_name": null,
        "last_name": null
    },
    "licenses": [],
    "has_assigned_users": false,
    "addresses": [
        {
            "uuid": "60c132a43b-5ab5-434a91-a4ec-d6e4704d4937",
            "address_1": "Chinchwad",
            "address_2": "",
            "address_3": "",
            "city": "Pune",
            "state": "MH",
            "subregion": "MH",
            "country": "IND",
            "postal_code": "412105",
            "translated_country_name": null,
            "translated_subregion_name": null,
            "latitude": "18.64742",
            "longitude": "73.80003",
            "timezone_name": "Asia/Kolkata",
            "types": ["main"],
            "cascaded_at": null,
            "is_current": true,
            "usage_types": [{ "name": "main" }]
        }
    ],
    "email_addresses": [],
    "telecom_addresses": [],
    "status": "planned",
    "team_memberships_count": 0,
    "cascaded_at": null,
    "address_usages": [
        {
            "uuid": "e58efc53223a-2028-4f7a-bc56-e8d72f4f2c18",
            "active": true,
            "usage_types": [{ "name": "main" }],
            "address": {
                "uuid": "60c123a43b-5ab5-4a91-a4ec-d6e4704d4937",
                "address_1": "Chinchwad",
                "address_2": "",
                "address_3": "",
                "city": "Pune",
                "subregion": "MH",
                "country": "IND",
                "postal_code": "412105",
                "translated_country_name": null,
                "translated_subregion_name": null,
                "latitude": "18.64742",
                "longitude": "73.80003",
                "timezone_name": "Asia/Kolkata"
            },
            "is_current": true,
            "cascaded_at": null
        }
    ],
    "active_pi_tm": null,
    "main_address": {
        "address_1": "Chinchwad",
        "address_2": "",
        "address_3": "",
        "city": "Pune",
        "state": "MH",
        "subregion": "MH",
        "country": "IND",
        "postal_code": "412105",
        "translated_country_name": null,
        "translated_subregion_name": null,
        "latitude": "18.64742",
        "longitude": "73.80003",
        "timezone_name": "Asia/Kolkata"
    }
}];

// 调整键映射:原SnakeCase键 => 目标键(指定替换或CamelCase)
const newKeyMap = {
    "uuid": "uuid",
    "site_number": "siteNumber",
    "name": "siteName",
    "main_address": "mainAddress",
    "team_memberships_count": "teamMembershipCount",
    "has_assigned_users": "hasAssignedUsers",
    "org_id": "clientDivisionOrganizationId",
    // 嵌套键如果需要单独替换也可以在这里添加,比如:"address.address_1": "street"
};

// SnakeCase转CamelCase工具函数
function camelize(text) {
    return text.toLowerCase().replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '')
        .replace(/^[A-Z]/, c => c.toLowerCase());
}

// 递归转换单个对象/数组
function transformItem(item) {
    // 处理数组:遍历每个元素递归转换
    if (Array.isArray(item)) {
        return item.map(transformItem);
    }
    // 处理非数组对象:遍历键值对转换
    if (typeof item === 'object' && item !== null) {
        return Object.entries(item).reduce((acc, [key, value]) => {
            // 确定新键:优先用映射表,否则自动转CamelCase
            const newKey = newKeyMap[key] || camelize(key);
            // 递归处理值
            acc[newKey] = transformItem(value);
            return acc;
        }, {});
    }
    // 基本类型直接返回
    return item;
}

// 转换数组中的所有对象
const transformArrayObject = (originalArray) => {
    return originalArray.map(transformItem);
};

// 测试输出
console.log("Result:", JSON.stringify(transformArrayObject(originalArray), null, 2));

代码说明

  1. 键映射表优化:newKeyMap直接使用原数据的SnakeCase键作为键,无需额外转换即可匹配,逻辑更清晰;
  2. 递归函数transformItem:统一处理数组、对象和基本类型,确保所有嵌套层级都被转换;
  3. CamelCase转换:工具函数camelize兼容带连字符、下划线的SnakeCase格式,自动转为标准CamelCase;
  4. 灵活性:如果需要对特定嵌套键单独替换,直接在newKeyMap中添加(如"address.address_1": "street"),但当前逻辑会自动转换嵌套键为CamelCase,无需额外配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:12:03