seek
The seek utility performs a deep fuzzy search within an object or array. It recursively scans all properties and values to determine if any of them match the search query based on a similarity threshold (tone).
Source Code
View Source Code
ts
import { assert } from '../function/assert';
import { similarity } from '../string/similarity';
import { isArray } from '../typed/isArray';
import { isNil } from '../typed/isNil';
import { isNumber } from '../typed/isNumber';
import { isObject } from '../typed/isObject';
import { isString } from '../typed/isString';
import { IS_WITHIN_ERROR_MSG, isWithin } from '../typed/isWithin';
/**
* Recursively checks if an object contains a value similar to the search string.
*
* @example
* ```ts
* const obj = { a: 'hello', b: { c: 'world' }, d: [1, 2, 3] };
*
* seek(obj, 'hello'); // true
* seek(obj, 'world'); // true
* seek(obj, 'foo'); // false
* seek(obj, 'hello', 0.5); // true
* seek(obj, 'hello', 0.8); // true
* seek(obj, 'hello', 1); // true
* seek(obj, 'hello', 1.5); // false
* seek(obj, 'hello', -1); // false
* seek(obj, 'hello', 0); // false
* ```
*
* @param item - The object to search within.
* @param query - The search string.
* @param [tone=1] - The similarity threshold.
*
* @returns Whether the object contains a matching value.
*/
function _seek<T>(item: T, query: string, tone: number): boolean {
if (isNil(item)) return false;
if (isString(item) || isNumber(item)) {
return similarity(String(item), query) >= tone;
}
if (isArray(item)) {
return (item as unknown[]).some((value) => _seek(value, query, tone));
}
if (isObject(item)) {
return Object.values(item as Record<string, unknown>).some((value) =>
isNil(value) ? false : _seek(value, query, tone),
);
}
return false;
}
export function seek<T>(item: T, query: string, tone = 1): boolean {
assert(isWithin(tone, 0, 1), IS_WITHIN_ERROR_MSG, { args: { max: 1, min: 0, tone }, type: TypeError });
return _seek(item, query, tone);
}Features
- Isomorphic: Works in both Browser and Node.js.
- Deep Scanning: Recursively searches through nested objects and arrays.
- Fuzzy Matching: Matches values even with partial strings or slight variations.
- Configurable Sensitivity: Adjust the "tone" to control how strict or loose the matching should be.
API
ts
function seek<T>(item: T, query: string, tone?: number): boolean;Parameters
item: The object, array, or value to search within.query: The search string (case-insensitive).tone: Optional. A similarity threshold between0and1(defaults to1for exact-like matching).
Returns
trueif a matching value is found anywhere within the structure; otherwise,false.
Examples
Deep Value Searching
ts
import { seek } from '@vielzeug/toolkit';
const data = {
id: 1,
meta: {
title: 'Hello World',
author: { name: 'Alice' },
},
tags: ['coding', 'typescript'],
};
seek(data, 'hello'); // true (matches title)
seek(data, 'alice'); // true (matches nested author name)
seek(data, 'type'); // true (matches tag)
seek(data, 'missing'); // falseUsing Similarity (Tone)
ts
import { seek } from '@vielzeug/toolkit';
const item = { label: 'Vielzeug Toolkit' };
// Loose match
seek(item, 'viel', 0.5); // true
// Strict match
seek(item, 'viel', 1.0); // falseImplementation Notes
- Throws
TypeErroriftoneis not between0and1. - Scans all enumerable properties and values.
- Case-insensitive comparison is used for string values.
- Internally leverages the
similarityutility.
See Also
- get: Safely retrieve a value at a specific known path.
- similarity: The underlying string comparison helper.
- isEqual: Check for exact deep equality.