Skip to content

Instantly share code, notes, and snippets.

@73nko
Last active November 14, 2022 09:32
Show Gist options
  • Save 73nko/e7bb45018180c759a6f472a42536f273 to your computer and use it in GitHub Desktop.
Save 73nko/e7bb45018180c759a6f472a42536f273 to your computer and use it in GitHub Desktop.
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