Skip to content

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']

注意事項

  1. 不可變性: 返回新對象,不修改原對象
  2. 路徑格式: 支持點分隔的字符串路徑或數組路徑
  3. 深層創建: 自動創建不存在的嵌套路徑
  4. 類型安全: 提供完整的TypeScript類型支持
  5. 性能: 對於深層嵌套對象,性能良好

與其他方法的區別

  • obj.prop = value: 直接修改原對象
  • lodash.set(): 類似功能,但radash的set更輕量
  • set(): radash提供的不可變設置方法

實際應用場景

  1. 狀態管理: 不可變地更新應用狀態
  2. 表單處理: 動態更新表單數據結構
  3. 配置管理: 更新配置文件中的嵌套設置
  4. API響應處理: 修改API響應數據結構
  5. 數據轉換: 構建復雜的嵌套數據結構

Released under the MIT License.