Last active
November 14, 2022 09:32
-
-
Save 73nko/e7bb45018180c759a6f472a42536f273 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const reEscapeChar = /\\(\\)?/g; | |
const rePropName = RegExp( | |
// Match anything that isn't a dot or bracket. | |
'[^.[\\]]+' + | |
'|' + | |
// Or match strings (supports escaping characters). | |
'(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2', | |
'g' | |
); | |
const stringToPath = (string: string) => { | |
const result = []; | |
if (string.charCodeAt(0) === '.'.charCodeAt(0)) { | |
result.push(''); | |
} | |
string.replace( | |
rePropName, | |
(match: string, expression: any, quote: any, subString: any): string => { | |
let key = match; | |
if (quote) { | |
key = subString.replace(reEscapeChar, '$1'); | |
} else if (expression) { | |
key = expression.trim(); | |
} | |
result.push(key); | |
return key; | |
} | |
); | |
return result; | |
}; | |
function toKey(value: number): string | number { | |
if (typeof value === 'string') return value; | |
const result = `${value}`; | |
return result == '0' && 1 / value == -Infinity ? '-0' : result; | |
} | |
const getInPath = ( | |
data: any[] | null, | |
path: string | any[], | |
value: any = true | |
): any | undefined => { | |
if (!data || typeof data !== 'object') | |
throw new TypeError('data must be an object or an array'); | |
if (typeof path !== 'string' && !Array.isArray(path)) | |
throw new TypeError('path must be a string or an array'); | |
let parsedPath = typeof path === 'string' ? stringToPath(path) : path; | |
const length = parsedPath.length; | |
let index = 0; | |
while (data != null && index < length) { | |
let key: string | number = toKey(parsedPath[index++]); | |
data = | |
key === 'n' | |
? data.find((d: any) => | |
getInPath(d, parsedPath.slice(index, length), value) | |
) | |
: data[key as unknown as any]; | |
} | |
if (typeof value === 'boolean') return data; | |
return data == value ? value : undefined; | |
}; | |
export function getAllInPath( | |
elems: any[], | |
path: string | string[], | |
value: any = true | |
) { | |
if (!Array.isArray(elems)) | |
throw new TypeError('The elements provided should be an array'); | |
return elems.filter((elem) => getInPath(elem, path, value)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment