All files / set set.ts

100% Statements 18/18
100% Branches 9/9
100% Functions 1/1
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61                                      1x 5x     5x 5x 5x 5x 10x 10x 10x 7x 5x   2x 2x     10x 5x   5x   10x   5x                                
/**
 * @description 设置 object 对象中对应 path 属性路径上的值,如果 path 不存在,则创建
 * @function set
 * @param {object} object - 要修改的对象
 * @param {(string | Array<string, number>)} path - 要设置的对象路径
 * @param {any} val - 要设置的值
 * @returns {object} 返回修改后的对象
 * @author liukun <919590347@qq.com>
 * @example
 * import { set } from '@wont/utils'
 * const obj = { "editVal": 0, "editArrVal": [0], "setNestVal": {}, "setArrVal": [] }
 * set(obj, 'editVal', 2)  // returns { "editVal": 2, "editArrVal": [0], "setNestVal": {}, "setArrVal": [] }
 * set(obj, 'editArrVal[0]', 2)  // returns { "editVal": 2, "editArrVal": [2], "setNestVal": {}, "setArrVal": [] }
 * set(obj, 'setNestVal.setNestVal.setNestVal', 2)  // returns { "editVal": 2, "editArrVal": [2], "setNestVal": { setNestVal: { setNestVal: 2 } }, "setArrVal": [] }
 * set(obj, 'setArrVal[1]', 2)  // returns { "editVal": 2, "editArrVal": [2], "setNestVal": { setNestVal: { setNestVal: 2 } }, "setArrVal": [ empty, 2] }
 * set(obj, ['arr', 0], 0)  // returns { "editVal": 2, "editArrVal": [2], "setNestVal": { setNestVal: { setNestVal: 2 } }, "setArrVal": [ empty, 2], arr: [0] }
 */
 
export type Path = string | (string | number)[]
export function set(object: object, path: Path, val: any): object {
  const paths = Array.isArray(path)
    ? path
    : path.replace(/\[(\d+)\]/g, '.$1').split('.')
  let current = object
  const len = paths.length
  let i = 0
  while (i < len) {
    const key = paths[i]
    const isLast = i === len - 1
    if (!current[key]) {
      if (isLast) {
        current[key] = val
      } else {
        const isArray = /^\d$/.test(paths[i + 1].toString())
        current[key] = isArray ? [] : {}
      }
    }
    if (isLast) {
      current[key] = val
    } else {
      current = current[key]
    }
    i += 1
  }
  return object
}
 
// const obj = {
//     editVal: 0,
//     editArrVal: [0],
//     setNestVal: {},
//     setArrVal: [],
// }
 
// console.log('set :>> ', JSON.stringify(set(obj, 'editVal', 2), null, 2))
// console.log('set :>> ', JSON.stringify(set(obj, 'editArrVal[0]', 2), null, 2))
// console.log('set :>> ', JSON.stringify(set(obj, 'setNestVal.setNestVal.setNestVal', 2), null, 2))
// console.log('set :>> ', JSON.stringify(set(obj, 'setArrVal[1]', 2), null, 2))
// TODO 循环引用问题待处理
// console.log('set :>> ', set(obj, 'obj.test', obj))