/** * 将例如像 a.b.c 或 a[1].b 的字符串转换为路径数组 * * @param string 要转换的字符串 */ export const keyToPath = (string: string) => { const result = []; if (string.charCodeAt(0) === '.'.charCodeAt(0)) { result.push(''); } string.replace( new RegExp( '[^.[\\]]+|\\[(?:([^"\'][^[]*)|(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))', 'g' ), (match, expression, quote, subString) => { let key = match; if (quote) { key = subString.replace(/\\(\\)?/g, '$1'); } else if (expression) { key = expression.trim(); } result.push(key); return ''; } ); return result; };
这段代码的作用是将一个复杂的对象属性路径字符串,例如 'a.b.c'
或 'a[1].b'
,转换为一个属性路径数组,例如 ['a', 'b', 'c']
或 ['a', '1', 'b']
。这个函数对于操作复杂嵌套的 JavaScript 对象非常有用。
以下是一个具体的使用示范:
const objectPath1 = 'a.b.c'; const pathArray1 = keyToPath(objectPath1); console.log(pathArray1); // ['a', 'b', 'c'] const objectPath2 = 'a[1].b'; const pathArray2 = keyToPath(objectPath2); console.log(pathArray2); // ['a', '1', 'b'] const objectPath3 = 'users[0].name.first'; const pathArray3 = keyToPath(objectPath3); console.log(pathArray3); // ['users', '0', 'name', 'first']
这样得到的属性路径数组,可以用于访问或者修改复杂嵌套的 JavaScript 对象。例如,你可以使用 Lodash 的 _.get()
和 _.set()
方法:
import _ from 'lodash'; const data = { users: [ { name: { first: 'John', last: 'Doe' } }, { name: { first: 'Jane', last: 'Doe' } }, ], }; const path = 'users[0].name.first'; const pathArray = keyToPath(path); // get value const value = _.get(data, pathArray); console.log(value); // 'John' // set value _.set(data, pathArray, 'Jack'); console.log(data.users[0].name.first); // 'Jack'
这是一个非常常见的模式,用于处理 JavaScript 中的深度嵌套对象。