mapKeys
将对象的键名映射为新的键名,支持自定义转换函数。
基础用法
typescript
import { mapKeys } from 'radash'
const obj = { name: 'Alice', age: 25, city: 'Beijing' }
const mapped = mapKeys(obj, key => key.toUpperCase())
console.log(mapped) // { NAME: 'Alice', AGE: 25, CITY: 'Beijing' }
语法
typescript
function mapKeys<T extends Record<string, any>, U extends Record<string, any>>(
obj: T,
fn: (key: keyof T) => string
): U
参数
obj
(T): 要映射键名的对象fn
(function): 映射函数,接收键名,返回新的键名
返回值
返回映射后的新对象,值保持不变。
示例
基本键名映射
typescript
import { mapKeys } from 'radash'
const obj = { name: 'Alice', age: 25, city: 'Beijing' }
// 将键转换为大写
const mapped1 = mapKeys(obj, key => key.toUpperCase())
console.log(mapped1) // { NAME: 'Alice', AGE: 25, CITY: 'Beijing' }
// 将键转换为小写
const mapped2 = mapKeys(obj, key => key.toLowerCase())
console.log(mapped2) // { name: 'Alice', age: 25, city: 'Beijing' }
添加前缀和后缀
typescript
import { mapKeys } from 'radash'
const obj = { name: 'Alice', age: 25, city: 'Beijing' }
// 添加前缀
const mapped1 = mapKeys(obj, key => `user_${key}`)
console.log(mapped1) // { user_name: 'Alice', user_age: 25, user_city: 'Beijing' }
// 添加后缀
const mapped2 = mapKeys(obj, key => `${key}_field`)
console.log(mapped2) // { name_field: 'Alice', age_field: 25, city_field: 'Beijing' }
// 添加前后缀
const mapped3 = mapKeys(obj, key => `data_${key}_info`)
console.log(mapped3) // { data_name_info: 'Alice', data_age_info: 25, data_city_info: 'Beijing' }
键名格式转换
typescript
import { mapKeys } from 'radash'
const obj = { userName: 'Alice', emailAddress: 'alice@example.com', phoneNumber: '123-456-7890' }
// 转换为下划线格式
const mapped1 = mapKeys(obj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped1) // { user_name: 'Alice', email_address: 'alice@example.com', phone_number: '123-456-7890' }
// 转换为短横线格式
const mapped2 = mapKeys(obj, key => key.replace(/([A-Z])/g, '-$1').toLowerCase())
console.log(mapped2) // { user-name: 'Alice', email-address: 'alice@example.com', phone-number: '123-456-7890' }
// 转换为点号格式
const mapped3 = mapKeys(obj, key => key.replace(/([A-Z])/g, '.$1').toLowerCase())
console.log(mapped3) // { user.name: 'Alice', email.address: 'alice@example.com', phone.number: '123-456-7890' }
处理特殊字符
typescript
import { mapKeys } from 'radash'
const obj = {
'user-name': 'Alice',
'email@domain': 'alice@example.com',
'phone_number': '123-456-7890',
'first.name': 'Alice',
'last name': 'Smith'
}
// 移除特殊字符
const mapped1 = mapKeys(obj, key => key.replace(/[^a-zA-Z0-9]/g, ''))
console.log(mapped1) // { username: 'Alice', emaildomain: 'alice@example.com', phonenumber: '123-456-7890', firstname: 'Alice', lastname: 'Smith' }
// 替换特殊字符为下划线
const mapped2 = mapKeys(obj, key => key.replace(/[^a-zA-Z0-9]/g, '_'))
console.log(mapped2) // { user_name: 'Alice', email_domain: 'alice@example.com', phone_number: '123-456-7890', first_name: 'Alice', last_name: 'Smith' }
处理数字和符号
typescript
import { mapKeys } from 'radash'
const obj = {
'user123': 'Alice',
'api_v1': 'v1',
'test@123': 'test',
'hello-world': 'hello',
'user_name_123': 'user'
}
// 移除数字
const mapped1 = mapKeys(obj, key => key.replace(/\d/g, ''))
console.log(mapped1) // { user: 'Alice', api_v: 'v1', test@: 'test', hello-world: 'hello', user_name_: 'user' }
// 保留字母和数字,移除其他字符
const mapped2 = mapKeys(obj, key => key.replace(/[^a-zA-Z0-9]/g, ''))
console.log(mapped2) // { user123: 'Alice', apiv1: 'v1', test123: 'test', helloworld: 'hello', username123: 'user' }
处理嵌套对象
typescript
import { mapKeys } from 'radash'
const obj = {
user: { name: 'Alice', age: 25 },
settings: { theme: 'dark', language: 'en' }
}
// 注意:mapKeys只处理顶层键名,不递归处理嵌套对象
const mapped = mapKeys(obj, key => `config_${key}`)
console.log(mapped)
// {
// config_user: { name: 'Alice', age: 25 },
// config_settings: { theme: 'dark', language: 'en' }
// }
处理数组值
typescript
import { mapKeys } from 'radash'
const obj = {
userNames: ['Alice', 'Bob', 'Charlie'],
emailAddresses: ['alice@example.com', 'bob@example.com'],
phoneNumbers: ['123-456-7890', '098-765-4321']
}
// 转换键名格式
const mapped = mapKeys(obj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// user_names: ['Alice', 'Bob', 'Charlie'],
// email_addresses: ['alice@example.com', 'bob@example.com'],
// phone_numbers: ['123-456-7890', '098-765-4321']
// }
处理函数值
typescript
import { mapKeys } from 'radash'
const obj = {
userHandler: () => 'hello',
emailValidator: function() { return true },
phoneProcessor: (x: number) => x * 2
}
// 转换键名格式
const mapped = mapKeys(obj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// user_handler: [Function: userHandler],
// email_validator: [Function: emailValidator],
// phone_processor: [Function: phoneProcessor]
// }
处理日期值
typescript
import { mapKeys } from 'radash'
const obj = {
createdAt: new Date('2023-01-01'),
updatedAt: new Date('2023-12-31'),
birthday: new Date('1998-05-15')
}
// 转换键名格式
const mapped = mapKeys(obj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// created_at: 2023-01-01T00:00:00.000Z,
// updated_at: 2023-12-31T00:00:00.000Z,
// birthday: 1998-05-15T00:00:00.000Z
// }
处理布尔值
typescript
import { mapKeys } from 'radash'
const obj = {
isActive: true,
isVerified: false,
isPremium: true,
isBlocked: false
}
// 转换键名格式
const mapped = mapKeys(obj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// is_active: true,
// is_verified: false,
// is_premium: true,
// is_blocked: false
// }
处理数字值
typescript
import { mapKeys } from 'radash'
const obj = {
userID: 1,
userScore: 95.5,
userRating: 4.8,
userCount: 0,
userPrice: -10.99
}
// 转换键名格式
const mapped = mapKeys(obj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// user_id: 1,
// user_score: 95.5,
// user_rating: 4.8,
// user_count: 0,
// user_price: -10.99
// }
处理API响应数据
typescript
import { mapKeys } from 'radash'
const apiResponse = {
responseStatus: 200,
responseData: { id: 1, name: 'Alice' },
responseMeta: { timestamp: new Date(), requestId: 'req_123456' }
}
// 移除前缀并转换格式
const mapped = mapKeys(apiResponse, key => {
const newKey = key.replace('response', '').toLowerCase()
return newKey.charAt(0).toLowerCase() + newKey.slice(1)
})
console.log(mapped)
// {
// status: 200,
// data: { id: 1, name: 'Alice' },
// meta: { timestamp: 2023-12-31T12:00:00.000Z, requestId: 'req_123456' }
// }
处理表单数据
typescript
import { mapKeys } from 'radash'
const formData = {
personalInfo: {
firstName: 'Alice',
lastName: 'Smith',
emailAddress: 'alice@example.com'
},
addressInfo: {
streetAddress: '123 Main St',
cityName: 'Beijing',
countryCode: 'CN'
}
}
// 转换键名格式
const mapped = mapKeys(formData, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// personal_info: { firstName: 'Alice', lastName: 'Smith', emailAddress: 'alice@example.com' },
// address_info: { streetAddress: '123 Main St', cityName: 'Beijing', countryCode: 'CN' }
// }
处理配置对象
typescript
import { mapKeys } from 'radash'
const config = {
serverConfig: {
hostName: 'localhost',
portNumber: 3000,
enableSSL: true
},
databaseConfig: {
connectionURL: 'postgresql://localhost:5432/mydb',
poolSettings: { minConnections: 1, maxConnections: 10 }
},
apiConfig: {
versionNumber: 'v1',
rateLimitSettings: { windowMilliseconds: 900000, maxRequests: 100 }
}
}
// 转换键名格式
const mapped = mapKeys(config, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// server_config: { hostName: 'localhost', portNumber: 3000, enableSSL: true },
// database_config: { connectionURL: 'postgresql://localhost:5432/mydb', poolSettings: { minConnections: 1, maxConnections: 10 } },
// api_config: { versionNumber: 'v1', rateLimitSettings: { windowMilliseconds: 900000, maxRequests: 100 } }
// }
处理错误对象
typescript
import { mapKeys } from 'radash'
const errorObject = {
errorName: 'ValidationError',
errorMessage: 'Invalid input',
errorDetails: {
fieldName: 'email',
fieldValue: 'invalid-email',
validationConstraints: { format: 'Must be a valid email' }
}
}
// 移除前缀并转换格式
const mapped = mapKeys(errorObject, key => {
const newKey = key.replace('error', '').toLowerCase()
return newKey.charAt(0).toLowerCase() + newKey.slice(1)
})
console.log(mapped)
// {
// name: 'ValidationError',
// message: 'Invalid input',
// details: { fieldName: 'email', fieldValue: 'invalid-email', validationConstraints: { format: 'Must be a valid email' } }
// }
处理日志数据
typescript
import { mapKeys } from 'radash'
const logEntry = {
logTimestamp: new Date(),
logLevel: 'ERROR',
logMessage: 'Database connection failed',
logContext: { userId: 123, requestId: 'req_456' },
errorInfo: { errorCode: 'ECONNREFUSED', errorMessage: 'Connection refused' }
}
// 移除前缀并转换格式
const mapped = mapKeys(logEntry, key => {
const newKey = key.replace('log', '').toLowerCase()
return newKey.charAt(0).toLowerCase() + newKey.slice(1)
})
console.log(mapped)
// {
// timestamp: 2023-12-31T12:00:00.000Z,
// level: 'ERROR',
// message: 'Database connection failed',
// context: { userId: 123, requestId: 'req_456' },
// errorInfo: { errorCode: 'ECONNREFUSED', errorMessage: 'Connection refused' }
// }
处理数据库查询结果
typescript
import { mapKeys } from 'radash'
const dbResult = {
recordID: 1,
productName: 'Product A',
categoryInfo: {
categoryID: 5,
categoryName: 'Electronics'
},
productVariants: [
{ variantID: 101, colorName: 'Red', priceValue: 99.99 },
{ variantID: 102, colorName: 'Blue', priceValue: 89.99 }
]
}
// 转换键名格式
const mapped = mapKeys(dbResult, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// record_id: 1,
// product_name: 'Product A',
// category_info: { categoryID: 5, categoryName: 'Electronics' },
// product_variants: [{ variantID: 101, colorName: 'Red', priceValue: 99.99 }, { variantID: 102, colorName: 'Blue', priceValue: 89.99 }]
// }
处理空对象和边界情况
typescript
import { mapKeys } from 'radash'
// 空对象
console.log(mapKeys({}, key => key)) // {}
// 只有一个键值对
console.log(mapKeys({ key: 'value' }, key => key.toUpperCase())) // { KEY: 'value' }
// 包含空值
console.log(mapKeys({ a: 1, b: null, c: undefined }, key => key.toUpperCase()))
// { A: 1, B: null, C: undefined }
处理复杂映射场景
typescript
import { mapKeys } from 'radash'
const complexObj = {
userProfile: {
personalInfo: {
fullName: 'Alice Smith',
ageValue: 25
},
userSettings: {
themePreference: 'dark',
notificationSettings: {
emailNotifications: true,
pushNotifications: false
}
}
},
systemInfo: {
versionNumber: '1.0.0',
environmentType: 'production'
}
}
// 转换键名格式
const mapped = mapKeys(complexObj, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// user_profile: { personalInfo: { fullName: 'Alice Smith', ageValue: 25 }, userSettings: { themePreference: 'dark', notificationSettings: { emailNotifications: true, pushNotifications: false } } },
// system_info: { versionNumber: '1.0.0', environmentType: 'production' }
// }
处理枚举映射
typescript
import { mapKeys } from 'radash'
const statusMap = {
userStatusActive: 'ACTIVE',
userStatusInactive: 'INACTIVE',
userStatusPending: 'PENDING',
userStatusSuspended: 'SUSPENDED'
}
// 转换键名格式
const mapped = mapKeys(statusMap, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// user_status_active: 'ACTIVE',
// user_status_inactive: 'INACTIVE',
// user_status_pending: 'PENDING',
// user_status_suspended: 'SUSPENDED'
// }
处理颜色映射
typescript
import { mapKeys } from 'radash'
const colorMap = {
primaryColor: '#FF0000',
secondaryColor: '#00FF00',
accentColor: '#0000FF',
warningColor: '#FFFF00',
successColor: '#800080'
}
// 转换键名格式
const mapped = mapKeys(colorMap, key => key.replace(/([A-Z])/g, '_$1').toLowerCase())
console.log(mapped)
// {
// primary_color: '#FF0000',
// secondary_color: '#00FF00',
// accent_color: '#0000FF',
// warning_color: '#FFFF00',
// success_color: '#800080'
// }
注意事项
- 映射函数: 映射函数必须返回字符串作为新键名
- 嵌套对象: 只处理顶层键名,不递归处理嵌套对象
- 数组值: 数组值会保持原样
- 不可变性: 返回新对象,不修改原对象
- 类型安全: 支持TypeScript类型推断
与其他方法的区别
Object.keys()
: 获取对象的所有键mapKeys()
: 映射键名并返回新对象mapValues()
: 映射值并返回新对象mapEntries()
: 映射键值对并返回新对象
实际应用场景
- 数据标准化: 统一对象键名的格式
- API适配: 适配不同API的键名格式
- 数据库映射: 映射数据库字段名
- 配置处理: 处理配置对象的键名格式
- 数据转换: 在不同系统间转换键名格式