UNPKG

super-utils-plus

Version:

A superior alternative to Lodash with improved performance, TypeScript support, and developer experience

93 lines (92 loc) 2.47 kB
import { isNil, isString, isArray } from '../utils/is'; /** * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned. * * @param object - The object to query * @param path - The path of the property to get * @param defaultValue - The value returned for undefined resolved values * @returns The resolved value * * @example * ```ts * const object = { 'a': [{ 'b': { 'c': 3 } }] }; * * get(object, 'a[0].b.c'); * // => 3 * * get(object, ['a', '0', 'b', 'c']); * // => 3 * * get(object, 'a.b.c', 'default'); * // => 'default' * ``` */ export function get(object, path, defaultValue) { if (isNil(object)) { return defaultValue; } const segments = isString(path) ? parsePath(path) : isArray(path) ? path : [path]; let result = object; for (let i = 0; i < segments.length; i++) { if (isNil(result)) { return defaultValue; } result = result[segments[i]]; } return isNil(result) ? defaultValue : result; } /** * Parses a string path into path segments. * Supports dot notation and bracket notation. * * @param path - The path to parse * @returns An array of path segments * * @example * ```ts * parsePath('a[0].b.c'); * // => ['a', 0, 'b', 'c'] * ``` */ function parsePath(path) { // Split by dots, but not within brackets const segments = []; let currentSegment = ''; let inBrackets = false; for (let i = 0; i < path.length; i++) { const char = path[i]; if (char === '[') { if (currentSegment) { segments.push(currentSegment); currentSegment = ''; } inBrackets = true; } else if (char === ']') { // If it's a number in brackets, convert to number if (/^\\d+$/.test(currentSegment)) { segments.push(parseInt(currentSegment, 10)); } else { segments.push(currentSegment); } currentSegment = ''; inBrackets = false; } else if (char === '.' && !inBrackets) { if (currentSegment) { segments.push(currentSegment); currentSegment = ''; } } else { currentSegment += char; } } if (currentSegment) { segments.push(currentSegment); } return segments; }