frontend-challenges icon indicating copy to clipboard operation
frontend-challenges copied to clipboard

474 - Immutability Helper - javascript

Open jsartisan opened this issue 2 months ago • 0 comments

index.js

const isObject = (obj) => typeof obj === 'object' && obj !== 'null'; 
/**
 * Immutability helper for nested updates.
 * @param {any} target - object or array to update
 * @param {object} spec - update specification
 * @returns {any} new object/array with updates applied
 */
export function update(data, command) {
  // for simple cases, which $command is in the first layer
  if ('$push' in command) {
    if (!Array.isArray(data)) {
      throw new Error('not array')
    }
    return [...data, ...command['$push']]
  }
  if ('$merge' in command) {
    if (!isObject(data)) {
      throw new Error('not object for $merge')
    }
    return {
      ...data,
      ...command['$merge']
    }
  }
  if ('$apply' in command) {
    return command['$apply'](data)
  }
  if ('$set' in command) {
    return command['$set']
  }
  
  // for cases with nested path
  // first shallow copy
  if (!isObject(data)) {
    throw new Error('not object for complex data')
  }
  const newData = Array.isArray(data) ? [...data] : {...data}

  for (const key of Object.keys(command)) {
    newData[key] = update(newData[key], command[key])
  }

  return newData
}

jsartisan avatar Sep 27 '25 04:09 jsartisan