修改嵌套层级很深对象的 key
实现一个函数,能够递归遍历深层嵌套对象,修改指定的 key 名称
问题
在实际开发中,我们经常需要处理后端返回的数据结构,有时需要将对象中的某些 key 进行重命名。当对象嵌套层级很深,且需要修改的 key 可能出现在任意层级时,就需要一个通用的解决方案来递归处理整个对象树。
例如:将对象中所有的 old_key 重命名为 newKey,无论它出现在哪一层。
解答
/**
* 修改嵌套对象中的 key
* @param {Object|Array} obj - 需要处理的对象或数组
* @param {String} oldKey - 旧的 key 名称
* @param {String} newKey - 新的 key 名称
* @returns {Object|Array} 返回修改后的新对象
*/
function renameDeepKey(obj, oldKey, newKey) {
// 处理 null 和 undefined
if (obj === null || obj === undefined) {
return obj;
}
// 处理数组
if (Array.isArray(obj)) {
return obj.map(item => renameDeepKey(item, oldKey, newKey));
}
// 处理非对象类型(基本类型)
if (typeof obj !== 'object') {
return obj;
}
// 处理对象
const newObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 判断当前 key 是否需要重命名
const currentKey = key === oldKey ? newKey : key;
const value = obj[key];
// 递归处理值
newObj[currentKey] = renameDeepKey(value, oldKey, newKey);
}
}
return newObj;
}
/**
* 批量修改多个 key(支持映射对象)
* @param {Object|Array} obj - 需要处理的对象或数组
* @param {Object} keyMap - key 映射关系,如 { oldKey1: 'newKey1', oldKey2: 'newKey2' }
* @returns {Object|Array} 返回修改后的新对象
*/
function renameDeepKeys(obj, keyMap) {
if (obj === null || obj === undefined) {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(item => renameDeepKeys(item, keyMap));
}
if (typeof obj !== 'object') {
return obj;
}
const newObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 查找映射关系,如果存在则使用新 key,否则保持原 key
const currentKey = keyMap[key] || key;
const value = obj[key];
newObj[currentKey] = renameDeepKeys(value, keyMap);
}
}
return newObj;
}
使用示例
// 示例 1: 修改单个 key
const data1 = {
user_name: 'Alice',
user_info: {
user_name: 'Bob',
age: 25,
address: {
user_name: 'Charlie'
}
},
list: [
{ user_name: 'David' },
{ user_name: 'Eve' }
]
};
const result1 = renameDeepKey(data1, 'user_name', 'userName');
console.log(result1);
/* 输出:
{
userName: 'Alice',
user_info: {
userName: 'Bob',
age: 25,
address: {
userName: 'Charlie'
}
},
list: [
{ userName: 'David' },
{ userName: 'Eve' }
]
}
*/
// 示例 2: 批量修改多个 key
const data2 = {
user_name: 'Alice',
user_age: 30,
user_info: {
user_name: 'Bob',
user_age: 25,
contact_email: 'bob@example.com'
}
};
const keyMap = {
user_name: 'userName',
user_age: 'userAge',
contact_email: 'email'
};
const result2 = renameDeepKeys(data2, keyMap);
console.log(result2);
/* 输出:
{
userName: 'Alice',
userAge: 30,
user_info: {
userName: 'Bob',
userAge: 25,
email: 'bob@example.com'
}
}
*/
// 示例 3: 处理复杂嵌套结构
const data3 = {
old_key: 'value1',
nested: {
old_key: 'value2',
deep: {
old_key: 'value3',
array: [
{ old_key: 'value4' },
{ old_key: 'value5', other: 'data' }
]
}
}
};
const result3 = renameDeepKey(data3, 'old_key', 'newKey');
console.log(JSON.stringify(result3, null, 2));
关键点
-
递归遍历:使用递归方式遍历对象的所有层级,确保能处理任意深度的嵌套结构
-
类型判断:需要区分处理数组、对象和基本类型,避免对非对象类型进行错误操作
-
数组处理:使用
map方法遍历数组,对每个元素递归调用函数 -
不可变性:创建新对象而不是修改原对象,避免副作用,符合函数式编程思想
-
hasOwnProperty 检查:使用
hasOwnProperty确保只处理对象自身的属性,不处理原型链上的属性 -
扩展性:提供批量修改版本
renameDeepKeys,支持一次性修改多个 key,提高效率 -
边界处理:正确处理
null、undefined等特殊值,增强函数的健壮性
目录