@v4fire/core
Version:
V4Fire core library
116 lines (90 loc) • 2.08 kB
text/typescript
/*!
* V4Fire Core
* https://github.com/V4Fire/Core
*
* Released under the MIT license
* https://github.com/V4Fire/Core/blob/master/LICENSE
*/
/**
* [[include:core/object/select/README.md]]
* @packageDocumentation
*/
import type { SelectParams } from 'core/object/select/interface';
export * from 'core/object/select/interface';
/**
* Finds an element from an object by the specified parameters
*
* @param obj - object to search
* @param [params] - search parameters
*/
export default function select<T = unknown>(obj: unknown, params: SelectParams = {}): CanUndef<T> {
const
{where, from} = params;
let
target = obj,
res;
if (from != null) {
target = Object.get(target, Object.isArray(from) ? from : String(from));
if (where == null) {
return Object.cast(target);
}
}
const cantSearch =
Object.isPrimitive(target) ||
where == null ||
Object.isArray(where) && where.length === 0;
if (cantSearch) {
return;
}
const
NULL = {};
where: for (let conditions = Array.concat([], where), i = 0; i < conditions.length; i++) {
const
where = conditions[i];
if (Object.isPlainObject(target)) {
const
match = getMatch(target, where);
if (match !== NULL) {
res = match;
break;
}
}
if (Object.isIterable(target)) {
const
iterator = target[Symbol.iterator]();
for (let el = iterator.next(); !el.done; el = iterator.next()) {
if (getMatch(el.value, where) !== NULL) {
res = el.value;
break where;
}
}
}
}
return res;
function getMatch(obj: unknown, where: Nullable<Dictionary>): unknown {
if (where == null || obj === where) {
return obj;
}
if (Object.isPrimitive(obj)) {
return NULL;
}
const
resolvedObj = <object>obj;
let
res = NULL;
for (let keys = Object.keys(where), i = 0; i < keys.length; i++) {
const
key = keys[i],
val = where[key];
if (!(key in resolvedObj)) {
continue;
}
if (!Object.fastCompare(val, resolvedObj[key])) {
res = NULL;
break;
}
res = resolvedObj;
}
return res;
}
}