UNPKG

@v4fire/core

Version:
116 lines (90 loc) 2.08 kB
/*! * 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; } }