set
安全地設置對象的嵌套屬性值,支持路徑字符串。
基礎用法
typescript
import { set } from 'radash'
const user = {
name: 'Alice',
address: {
city: 'Beijing'
}
}
const updated = set(user, 'address.country', 'China')
console.log(updated.address.country) // 'China'
const updated2 = set(user, 'profile.email', 'alice@example.com')
console.log(updated2.profile.email) // 'alice@example.com'
語法
typescript
function set<T extends Record<string, any>>(
obj: T,
path: string | string[],
value: any
): T
參數
obj
(T): 要修改的對象path
(string | string[]): 屬性路徑,可以是字符串(用點分隔)或數組value
(any): 要設置的值
返回值
返回修改後的新對象,原對象不會被修改。
示例
基本屬性設置
typescript
import { set } from 'radash'
const user = {
name: 'Alice',
age: 25
}
const updated = set(user, 'email', 'alice@example.com')
console.log(updated)
// {
// name: 'Alice',
// age: 25,
// email: 'alice@example.com'
// }
嵌套屬性設置
typescript
import { set } from 'radash'
const user = {
name: 'Alice',
address: {
city: 'Beijing'
}
}
const updated = set(user, 'address.country', 'China')
console.log(updated)
// {
// name: 'Alice',
// address: {
// city: 'Beijing',
// country: 'China'
// }
// }
創建深層嵌套
typescript
import { set } from 'radash'
const user = {
name: 'Alice'
}
const updated = set(user, 'profile.address.details.street', 'Main Street')
console.log(updated)
// {
// name: 'Alice',
// profile: {
// address: {
// details: {
// street: 'Main Street'
// }
// }
// }
// }
使用數組路徑
typescript
import { set } from 'radash'
const user = {
name: 'Alice',
profile: {
address: {
city: 'Beijing'
}
}
}
// 使用數組路徑
const updated = set(user, ['profile', 'address', 'country'], 'China')
console.log(updated.profile.address.country) // 'China'
設置數組元素
typescript
import { set } from 'radash'
const user = {
name: 'Alice',
hobbies: ['reading', 'swimming']
}
const updated = set(user, 'hobbies.2', 'coding')
console.log(updated.hobbies) // ['reading', 'swimming', 'coding']
const updated2 = set(user, 'hobbies.0', 'writing')
console.log(updated2.hobbies) // ['writing', 'swimming']
處理復雜對象
typescript
import { set } from 'radash'
const user = {
id: 1,
name: 'Alice',
settings: {
theme: 'light',
notifications: {
email: true
}
}
}
const updated = set(user, 'settings.notifications.push', false)
console.log(updated.settings.notifications)
// {
// email: true,
// push: false
// }
更新API響應
typescript
import { set } from 'radash'
function updateUserProfile(user: any, updates: Record<string, any>) {
let updatedUser = user
Object.entries(updates).forEach(([path, value]) => {
updatedUser = set(updatedUser, path, value)
})
return updatedUser
}
const user = {
id: 1,
name: 'Alice',
profile: {
email: 'alice@example.com',
address: {
city: 'Beijing'
}
}
}
const updates = {
'profile.email': 'alice.new@example.com',
'profile.address.country': 'China',
'profile.phone': '+86 123 4567 8900'
}
const updated = updateUserProfile(user, updates)
console.log(updated)
處理表單數據
typescript
import { set } from 'radash'
function processFormData(formData: FormData) {
let data: any = {}
for (const [key, value] of formData.entries()) {
data = set(data, key, value)
}
return data
}
// 模擬表單數據
const mockFormData = new FormData()
mockFormData.append('user.firstName', 'Alice')
mockFormData.append('user.lastName', 'Smith')
mockFormData.append('user.email', 'alice@example.com')
mockFormData.append('address.street', '123 Main St')
mockFormData.append('address.city', 'Beijing')
mockFormData.append('preferences.newsletter', 'true')
const result = processFormData(mockFormData)
console.log(result)
// {
// user: {
// firstName: 'Alice',
// lastName: 'Smith',
// email: 'alice@example.com'
// },
// address: {
// street: '123 Main St',
// city: 'Beijing'
// },
// preferences: {
// newsletter: 'true'
// }
// }
更新配置對象
typescript
import { set } from 'radash'
function updateConfig(config: any, updates: Record<string, any>) {
let updatedConfig = config
Object.entries(updates).forEach(([path, value]) => {
updatedConfig = set(updatedConfig, path, value)
})
return updatedConfig
}
const config = {
server: {
port: 3000,
host: 'localhost'
},
database: {
url: 'postgresql://localhost:5432/mydb'
}
}
const updates = {
'server.port': 8080,
'server.timeout': 5000,
'database.pool.min': 1,
'database.pool.max': 10,
'features.cache': true
}
const updated = updateConfig(config, updates)
console.log(updated)
處理嵌套數組
typescript
import { set } from 'radash'
const data = {
departments: [
{
name: 'Engineering',
employees: [
{ id: 1, name: 'Alice', role: 'Developer' }
]
}
]
}
const updated = set(data, 'departments.0.employees.1', {
id: 2,
name: 'Bob',
role: 'Manager'
})
console.log(updated.departments[0].employees)
// [
// { id: 1, name: 'Alice', role: 'Developer' },
// { id: 2, name: 'Bob', role: 'Manager' }
// ]
條件設置
typescript
import { set } from 'radash'
function setConditionalValue(obj: any, condition: boolean, path: string, trueValue: any, falseValue: any) {
const value = condition ? trueValue : falseValue
return set(obj, path, value)
}
const user = {
name: 'Alice',
isPremium: true
}
const updated = setConditionalValue(
user,
user.isPremium,
'settings.theme',
'dark',
'light'
)
console.log(updated.settings.theme) // 'dark'
批量更新
typescript
import { set } from 'radash'
function batchSet(obj: any, updates: Array<{ path: string; value: any }>) {
let result = obj
updates.forEach(({ path, value }) => {
result = set(result, path, value)
})
return result
}
const user = {
name: 'Alice',
profile: {
email: 'alice@example.com'
}
}
const updates = [
{ path: 'profile.phone', value: '+86 123 4567 8900' },
{ path: 'profile.address.city', value: 'Beijing' },
{ path: 'settings.theme', value: 'dark' },
{ path: 'settings.notifications', value: true }
]
const updated = batchSet(user, updates)
console.log(updated)
處理動態路徑
typescript
import { set } from 'radash'
function setNestedValue(obj: any, pathParts: string[], value: any) {
const path = pathParts.join('.')
return set(obj, path, value)
}
const user = {
name: 'Alice'
}
const updated = setNestedValue(user, ['profile', 'address', 'city'], 'Beijing')
console.log(updated.profile.address.city) // 'Beijing'
處理復雜嵌套結構
typescript
import { set } from 'radash'
const complexData = {
company: {
departments: [
{
name: 'Engineering',
teams: [
{
name: 'Frontend',
members: [
{ id: 1, name: 'Alice', skills: ['React'] }
]
}
]
}
]
}
}
const updated = set(complexData, 'company.departments.0.teams.0.members.0.skills.1', 'TypeScript')
console.log(updated.company.departments[0].teams[0].members[0].skills)
// ['React', 'TypeScript']
處理不同類型值
typescript
import { set } from 'radash'
const user = {
name: 'Alice'
}
// 設置不同類型的值
const updated1 = set(user, 'age', 25)
const updated2 = set(updated1, 'isActive', true)
const updated3 = set(updated2, 'tags', ['developer', 'frontend'])
const updated4 = set(updated3, 'settings', { theme: 'dark' })
const updated5 = set(updated4, 'lastLogin', null)
console.log(updated5)
// {
// name: 'Alice',
// age: 25,
// isActive: true,
// tags: ['developer', 'frontend'],
// settings: { theme: 'dark' },
// lastLogin: null
// }
處理錯誤情況
typescript
import { set } from 'radash'
const user = {
name: 'Alice',
address: {
city: 'Beijing'
}
}
// 設置到null或undefined對象
const updated1 = set(user, 'address.country', 'China')
console.log(updated1.address.country) // 'China'
// 設置到不存在的路徑
const updated2 = set(user, 'profile.email', 'alice@example.com')
console.log(updated2.profile.email) // 'alice@example.com'
// 設置到數組索引
const updated3 = set(user, 'hobbies.0', 'reading')
console.log(updated3.hobbies) // ['reading']
注意事項
- 不可變性: 返回新對象,不修改原對象
- 路徑格式: 支持點分隔的字符串路徑或數組路徑
- 深層創建: 自動創建不存在的嵌套路徑
- 類型安全: 提供完整的TypeScript類型支持
- 性能: 對於深層嵌套對象,性能良好
與其他方法的區別
obj.prop = value
: 直接修改原對象lodash.set()
: 類似功能,但radash的set更輕量set()
: radash提供的不可變設置方法
實際應用場景
- 狀態管理: 不可變地更新應用狀態
- 表單處理: 動態更新表單數據結構
- 配置管理: 更新配置文件中的嵌套設置
- API響應處理: 修改API響應數據結構
- 數據轉換: 構建復雜的嵌套數據結構