Skip to content
VersionSize

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).

Implementation

View Source Code
ts
import { assert } from '../function/assert';
import { similarity } from '../string/similarity';
import { is } from '../typed/is';
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.
 */
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 });

  if (is('nil', item)) return false;

  if (is('string', item) || is('number', item)) {
    // Lowercase both sides for case-insensitive comparison
    return similarity(item, query) >= tone;
  }

  // Handle arrays
  if (is('array', item)) {
    return (item as unknown[]).some((value) => seek(value, query, tone));
  }

  // Handle objects but skip dates/regex/etc which are technically objects
  if (is('object', item)) {
    return Object.values(item as Record<string, unknown>).some((value) =>
      is('nil', value) ? false : seek(value, query, tone),
    );
  }

  return false;
}

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(obj: any, searchValue: string, tolerance?: number): boolean;

Parameters

  • item: The object, array, or value to search within.
  • query: The search string (case-insensitive).
  • tone: Optional. A similarity threshold between 0 and 1 (defaults to 1 for exact-like matching).

Returns

  • true if 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'); // false

Using 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); // false

Implementation Notes

  • Throws TypeError if tone is not between 0 and 1.
  • Scans all enumerable properties and values.
  • Case-insensitive comparison is used for string values.
  • Internally leverages the similarity utility.

See Also

  • path: Safely retrieve a value at a specific known path.
  • similarity: The underlying string comparison helper.
  • isEqual: Check for exact deep equality.