Skip to content

getKey

根据字符串路径读取对象(数组)深层属性

引入版本

0.50.0

Demo

ts
import { getKey } from '@wyfex/iutils'

/**
 * 对象
 */
const obj = {
  user: { name: 'Symbol(王独秀)', age: 0, address: null, sex: '' },
  list: [10, 20, { code: 'A001', inner: [100] }],
  'my key': 666,
  '-1': '普通key负一字符串'
}

// 正常深层取值
console.log(getKey(obj, 'user.name')) // "Symbol(王独秀)"

// 数组下标语法
console.log(getKey(obj, 'list[2].code')) // "A001"

// 路径混用 . 和 [] 多种写法
console.log(getKey(obj, 'list[2].inner[0]')) // 100

// 值为0(重点测试:不能被default覆盖)
console.log(getKey(obj, 'user.age', 99)) // 0

// 值为null(有效数值,不触发默认)
console.log(getKey(obj, 'user.address', 'empty')) // null

// 值为''(有效数值,不触发默认)
console.log(getKey(obj, 'user.sex', 'empty')) // ''

// 路径不存在,返回默认值
console.log(getKey(obj, 'user.phone', '123456')) // "123456"

// 数组直接索引
console.log(getKey(obj.list, 1)) // 20

// 带引号下标支持
console.log(getKey(obj, '["my key"]')) // 666

// 对象key字面量 "-1",不做负索引转换
console.log(getKey(obj, '["-1"]')) // "普通key负一字符串"

console.log('==================')

/**
 * 一维数组
 */
const arr = ['Symbol(王独秀)', 0, false, null, '', undefined, true]

// 根为数组,直接数字路径字符串
console.log(getKey(arr, '[0]', '默认值')) // 'Symbol(王独秀)'
console.log(getKey(arr, '[1]', '默认值')) // 0 假值(undefined除外)不会被默认值覆盖,下同
console.log(getKey(arr, '[2]', '默认值')) // false
console.log(getKey(arr, '[3]', '默认值')) // null
console.log(getKey(arr, '[4]', '默认值')) // ''
console.log(getKey(arr, '[5]', '默认值')) // '默认值'

// 负索引
console.log(getKey(arr, '[-1]', '默认值')) // true
console.log(getKey(arr, '[-99]', '超出范围')) // "超出范围"

// 数组索引越界,返回默认值
console.log(getKey(arr, '[99]', 'missing')) // "missing"

// 传入 number 类型 path(数组索引简写)
console.log(getKey(arr, 0)) // 'Symbol(王独秀)'

console.log('==================')

/**
 * 二维数组
 */
const twoDArr = [
  [11, 22],
  [33, { label: 'test' }]
]
// 二维数组取值
console.log(getKey(twoDArr, '[0][1]')) // 22
console.log(getKey(twoDArr, '[1][1].label')) // "test"

// 二维数组负索引嵌套
console.log(getKey(twoDArr, '[-1][-1].label')) // "test"

// 传入 number 类型 path(数组索引简写)
console.log(getKey(twoDArr, 1)) // [33, { label: "test" }]

console.log('==================')

/**
 * 对象数组
 */
const list1 = [
  { id: 1, tags: ['vue', 'ts'] },
  { id: 2, tags: ['vite'] }
]
// 对象数组深层数组路径
console.log(getKey(list1, '[0].tags[1]')) // "ts"
console.log(getKey(list1, '[1].tags[0]')) // "vite"

// 对象数组多层负索引混用
console.log(getKey(list1, '[-1].tags[-1]')) // "vite"
console.log(getKey(list1, '[-1].tags[-5]', '无数据')) // "无数据"

// 数组内部不存在的属性
console.log(getKey(list1, '[0].tags[9]', 'empty')) // "empty"

const list2 = [{ a: { b: [1] } }, { c: 2 }]
console.log(getKey(list2, '[0].a.b[0]')) // 1
console.log(getKey(list2, '[1].c')) // 2
console.log(getKey(list2, '[0].a.b[0][2].c', 3)) // 3

console.log('==================')

/**
 * 多维数组
 */
// 多维混合,连续多层数组嵌套
const deepArr1 = [[[[{ val: 999 }]]]]
console.log(getKey(deepArr1, '[0][0][0][0].val')) // 999

// 多维连续负索引
const deepArr2 = [
  [1, 2, 3],
  [4, 5, 6]
]
console.log(getKey(deepArr2, '[-1][-2]')) // 5

基于 MIT 许可发布