Skip to content

A powerful, zero-dependency filtering library that brings MongoDB-style operators, SQL wildcards, and intelligent autocomplete to TypeScript arrays. Think of it as Array.filter() on steroids! ๐Ÿ’ช

License

Notifications You must be signed in to change notification settings

mcabreradev/filter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Filter

A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies.

Why @mcabreradev/filter?

Go beyond JavaScript's native Array.filter() with a library that understands your data:

  • ๐ŸŽฏ SQL-like Wildcards - Use % and _ for flexible pattern matching
  • ๐Ÿ” Deep Object Filtering - Search through nested objects up to configurable depths
  • โšก Zero Dependencies - Lightweight and production-ready (only Zod for runtime validation)
  • ๐Ÿ”’ Type-Safe - Built with strict TypeScript for maximum reliability
  • โœจ Smart Autocomplete - IntelliSense suggests only valid operators for each property type
  • ๐ŸŽจ Multiple Strategies - String patterns, objects, predicates, operators, or custom comparators
  • ๐Ÿš€ Performance Optimized - Optional caching and regex compilation optimization
  • ๐Ÿ“ฆ MongoDB-Style Operators - 30+ operators for advanced filtering (v5.0.0+)
  • ๐ŸŒ Geospatial Operators - Location-based filtering with $near, $geoBox, $geoPolygon (v5.6.0+)
  • ๐Ÿ“… Date/Time Operators - Temporal filtering with $recent, $upcoming, $dayOfWeek, $age (v5.6.0+)
  • ๐Ÿ’จ Lazy Evaluation - Process large datasets efficiently with generators (v5.1.0+)
  • ๐ŸŽจ Framework Integrations - React, Vue, and Svelte support (v5.3.0+)
  • ๐Ÿงช Battle-Tested - 613+ tests ensuring reliability

Installation

# Using npm npm install @mcabreradev/filter # Using yarn yarn add @mcabreradev/filter # Using pnpm pnpm add @mcabreradev/filter

Requirements: Node.js >= 20, TypeScript 5.0+ (optional)


Quick Start

import { filter } from '@mcabreradev/filter'; const users = [ { name: 'Alice', email: 'alice@example.com', age: 30, city: 'Berlin' }, { name: 'Bob', email: 'bob@example.com', age: 25, city: 'London' }, { name: 'Charlie', email: 'charlie@example.com', age: 35, city: 'Berlin' } ]; // Simple string matching (case-insensitive by default) filter(users, 'Berlin'); // โ†’ Returns Alice and Charlie // Wildcard patterns (SQL-like) filter(users, '%alice%'); // โ†’ Returns Alice // Object-based filtering filter(users, { city: 'Berlin', age: 30 }); // โ†’ Returns Alice // Negation support filter(users, '!London'); // โ†’ Returns Alice and Charlie // Predicate functions filter(users, (user) => user.age > 28); // โ†’ Returns Alice and Charlie // v5.0.0: MongoDB-style operators filter(users, { age: { $gte: 25, $lt: 35 } }); // โ†’ Returns Bob and Alice filter(users, { city: { $in: ['Berlin', 'Paris'] } }); // โ†’ Returns Alice and Charlie filter(users, { name: { $startsWith: 'A' } }); // โ†’ Returns Alice

๐ŸŽฎ Try it live in the Interactive Playground!


Framework Integrations ๐ŸŽจ

New in v5.4.0: Full framework integration support for React, Vue, and Svelte!

React Hooks

import { useFilter, useDebouncedFilter, usePaginatedFilter } from '@mcabreradev/filter'; function UserList() { const { filtered, isFiltering } = useFilter(users, { active: true }); return ( <div> {isFiltering && <span>Filtering...</span>} {filtered.map(user => <User key={user.id} {...user} />)}  </div> ); } function SearchUsers() { const [search, setSearch] = useState(''); const { filtered, isPending } = useDebouncedFilter(users, search, { delay: 300 }); return ( <div> <input onChange={(e) => setSearch(e.target.value)} /> {isPending && <span>Loading...</span>} {filtered.map(user => <User key={user.id} {...user} />)}  </div> ); }

Vue Composables

<script setup> import { ref } from 'vue'; import { useFilter, usePaginatedFilter } from '@mcabreradev/filter';  const searchTerm = ref(''); const { filtered, isFiltering } = useFilter(users, searchTerm); </script> <template> <div> <span v-if="isFiltering">Filtering...</span> <div v-for="user in filtered" :key="user.id">{{ user.name }}</div> </div> </template>

Svelte Stores

<script> import { writable } from 'svelte/store'; import { useFilter } from '@mcabreradev/filter';  const searchTerm = writable(''); const { filtered, isFiltering } = useFilter(users, searchTerm); </script> {#if $isFiltering} <span>Filtering...</span> {/if} {#each $filtered as user (user.id)} <div>{user.name}</div> {/each}

Features:

  • โœ… React Hooks: useFilter, useFilteredState, useDebouncedFilter, usePaginatedFilter
  • โœ… Vue Composables: Full Composition API support with reactivity
  • โœ… Svelte Stores: Reactive stores with derived state
  • โœ… TypeScript: Full type safety with generics
  • โœ… SSR Compatible: Works with Next.js, Nuxt, and SvelteKit

See Framework Integrations Guide for complete documentation.


Core Features

Basic Filtering

Filter by simple values across all object properties:

const products = [ { id: 1, name: 'Laptop', price: 1200 }, { id: 2, name: 'Mouse', price: 25 }, { id: 3, name: 'Monitor', price: 450 } ]; // String search filter(products, 'Laptop'); // โ†’ [{ id: 1, ... }] // Number search filter(products, 25); // โ†’ [{ id: 2, ... }] // Boolean search filter(tasks, true); // Finds all completed tasks

Wildcard Patterns

SQL-like wildcards for flexible matching:

// % matches zero or more characters filter(users, '%alice%'); // Contains 'alice' filter(users, 'Al%'); // Starts with 'Al' filter(users, '%son'); // Ends with 'son' // _ matches exactly one character filter(codes, 'A_'); // 'A1', 'A2', but not 'AB1' filter(ids, 'user-10_'); // 'user-101', 'user-102' // Negation with ! filter(users, '!admin'); // Exclude admin filter(files, '!%.pdf'); // Exclude PDFs

Object-Based Filtering

Match by specific properties (AND logic):

// Single property filter(products, { category: 'Electronics' }); // Multiple properties (all must match) filter(products, { category: 'Electronics', price: 1200, inStock: true }); // Nested objects filter(users, { address: { city: 'Berlin' }, settings: { theme: 'dark' } });

MongoDB-Style Operators (v5.0.0+)

Powerful operators for advanced filtering with intelligent autocomplete - TypeScript suggests only valid operators for each property type!

interface Product { name: string; price: number; tags: string[]; inStock: boolean; } // TypeScript autocompletes operators based on property types filter(products, { price: { // Suggests: $gt, $gte, $lt, $lte, $eq, $ne $gte: 100, $lte: 500 }, name: { // Suggests: $startsWith, $endsWith, $contains, $regex, $match, $eq, $ne $startsWith: 'Laptop' }, tags: { // Suggests: $in, $nin, $contains, $size $contains: 'sale' }, inStock: { // Suggests: $eq, $ne $eq: true } });

๐Ÿ“– Learn more about autocomplete โ†’

Comparison Operators

// Greater than / Less than filter(products, { price: { $gt: 100 } }); filter(products, { price: { $lte: 500 } }); // Range queries filter(products, { price: { $gte: 100, $lte: 500 } }); // Date ranges filter(orders, { date: { $gte: new Date('2025-01-01'), $lte: new Date('2025-12-31') } }); // Not equal filter(users, { role: { $ne: 'guest' } });

Available: $gt, $gte, $lt, $lte, $eq, $ne

Array Operators

// In / Not in array filter(products, { category: { $in: ['Electronics', 'Books'] } }); filter(products, { status: { $nin: ['archived', 'deleted'] } }); // Array contains value filter(products, { tags: { $contains: 'sale' } }); // Array size filter(products, { images: { $size: 3 } });

Available: $in, $nin, $contains, $size

String Operators

// Starts with / Ends with filter(users, { email: { $endsWith: '@company.com' } }); filter(files, { name: { $startsWith: 'report-' } }); // Contains substring filter(articles, { title: { $contains: 'typescript' } }); // Regular expressions filter(users, { email: { $regex: '^[a-z]+@example\\.com$' } }); filter(users, { phone: { $regex: /^\+1-\d{3}-\d{4}$/ } }); // $match is an alias for $regex filter(users, { username: { $match: '^[a-z]+\\d+$' } });

Available: $startsWith, $endsWith, $contains, $regex, $match

Logical Operators (v5.2.0+)

Combine multiple conditions with logical operators:

// $and - All conditions must match filter(products, { $and: [ { category: 'Electronics' }, { inStock: true }, { price: { $lt: 1000 } } ] }); // $or - At least one condition must match filter(products, { $or: [ { category: 'Electronics' }, { category: 'Accessories' } ] }); // $not - Negates the condition filter(products, { $not: { category: 'Furniture' } }); // Complex nested queries filter(products, { $and: [ { inStock: true }, { $or: [ { rating: { $gte: 4.5 } }, { price: { $lt: 50 } } ] }, { $not: { category: 'Clearance' } } ] }); // Combine with field-level conditions filter(products, { category: 'Electronics', $and: [ { price: { $gte: 100 } }, { $or: [{ inStock: true }, { preOrder: true }] } ] });

Available: $and, $or, $not

Combining Operators

// Multiple operators, multiple properties filter(products, { price: { $gte: 100, $lte: 500 }, category: { $in: ['Electronics', 'Accessories'] }, name: { $startsWith: 'Pro' }, inStock: { $eq: true } });

Array OR Syntax (v5.5.0+)

New in v5.5.0: Intuitive array-based OR filtering without explicit $in operator!

// Array syntax - clean and intuitive (OR logic) filter(products, { category: ['Electronics', 'Books'] }); // Equivalent to: { category: { $in: ['Electronics', 'Books'] } } // Multiple properties with array OR (independent OR conditions) filter(products, { category: ['Electronics', 'Accessories'], price: [100, 200, 300] }); // Logic: (category === 'Electronics' OR category === 'Accessories')  // AND (price === 100 OR price === 200 OR price === 300) // Combining array OR with other conditions (AND logic) filter(users, { city: ['Berlin', 'Paris'], age: 30, role: ['admin', 'moderator'] }); // Logic: (city === 'Berlin' OR city === 'Paris')  // AND age === 30  // AND (role === 'admin' OR role === 'moderator') // Works with wildcards filter(users, { email: ['%@gmail.com', '%@yahoo.com'] }); // Matches emails ending with @gmail.com OR @yahoo.com // Empty array matches nothing filter(products, { category: [] }); // โ†’ Returns empty array

Benefits:

  • โœจ More intuitive than $in operator
  • ๐Ÿ“ Cleaner, more readable code
  • ๐Ÿ”„ 100% backward compatible
  • ๐ŸŽฏ Works with strings, numbers, booleans
  • ๐ŸŒŸ Supports wildcard patterns

Geospatial Operators (v5.6.0+)

New in v5.6.0: Filter by geographic location with powerful spatial operators!

import { filter, type GeoPoint } from '@mcabreradev/filter'; interface Restaurant { name: string; location: GeoPoint; rating: number; } const userLocation: GeoPoint = { lat: 52.52, lng: 13.405 }; // $near - Find points within radius filter(restaurants, { location: { $near: { center: userLocation, maxDistanceMeters: 5000 } } }); // $geoBox - Bounding box queries filter(stores, { location: { $geoBox: { southwest: { lat: 52.5, lng: 13.3 }, northeast: { lat: 52.6, lng: 13.5 } } } }); // $geoPolygon - Polygon containment filter(properties, { location: { $geoPolygon: { points: [ { lat: 51.5074, lng: -0.1278 }, { lat: 51.5100, lng: -0.1200 }, { lat: 51.5050, lng: -0.1150 }, { lat: 51.5020, lng: -0.1250 } ] } } }); // Combine with other filters filter(restaurants, { location: { $near: { center: userLocation, maxDistanceMeters: 3000 } }, rating: { $gte: 4.5 }, isOpen: true });

Available: $near, $geoBox, $geoPolygon

Features:

  • ๐ŸŒ Location-based filtering
  • ๐Ÿ“ Accurate distance calculation
  • ๐Ÿ—บ๏ธ Bounding box and polygon support
  • โšก Fast spherical law of cosines
  • ๐Ÿ”’ Automatic coordinate validation

See Geospatial Operators Guide for complete documentation.

Date/Time Operators (v5.6.0+)

New in v5.6.0: Filter by relative time, days of week, time of day, and age calculations!

import { filter } from '@mcabreradev/filter'; interface Event { name: string; date: Date; startTime: Date; } const events: Event[] = [...]; // Events in next 7 days filter(events, { date: { $upcoming: { days: 7 } } }); // Recent events (last 24 hours) filter(events, { date: { $recent: { hours: 24 } } }); // Weekday events only filter(events, { date: { $dayOfWeek: [1, 2, 3, 4, 5] } }); // Business hours events (9 AM - 5 PM) filter(events, { startTime: { $timeOfDay: { start: 9, end: 17 } } }); // Adult users (18+) filter(users, { birthDate: { $age: { min: 18 } } }); // Weekend events filter(events, { date: { $isWeekend: true } }); // Combine multiple datetime conditions filter(events, { date: { $upcoming: { days: 7 }, $dayOfWeek: [1, 2, 3, 4, 5] }, startTime: { $timeOfDay: { start: 9, end: 17 } } });

Available: $recent, $upcoming, $dayOfWeek, $timeOfDay, $age, $isWeekday, $isWeekend, $isBefore, $isAfter

Features:

  • ๐Ÿ“… Relative time filtering (last/next N days/hours/minutes)
  • ๐Ÿ—“๏ธ Day of week filtering (0-6)
  • โฐ Time of day filtering (0-23 hours)
  • ๐ŸŽ‚ Age calculation (years/months/days)
  • ๐Ÿ“Š Weekday/weekend filtering
  • ๐Ÿ”’ Full TypeScript support with autocomplete

See Date/Time Operators Guide for complete documentation.

Predicate Functions

For complex custom logic:

// Simple predicate filter(numbers, (n) => n > 5); // Complex conditions filter(products, (product) => product.price < 100 && product.inStock && product.rating >= 4.0 ); // Type-safe with TypeScript filter<Product>(products, (p: Product): boolean => p.price > 100 && p.name.includes('Pro') );

Lazy Evaluation (v5.1.0+)

Efficiently process large datasets with lazy evaluation:

import { filterLazy, filterFirst, filterExists, filterCount, toArray, take, map } from '@mcabreradev/filter'; // Lazy evaluation - process items on-demand const filtered = filterLazy(millionRecords, { active: true }); for (const item of filtered) { process(item); if (shouldStop) break; // Early exit - stops processing immediately } // Find first N matches with early exit optimization const first10 = filterFirst(users, { premium: true }, 10); // Check existence without processing all items const hasAdmin = filterExists(users, { role: 'admin' }); // Count matching items const activeCount = filterCount(users, { active: true }); // Compose lazy operations for powerful pipelines const result = toArray( take( map(filterLazy(users, { active: true }), u => u.name), 100 ) ); // Chunked processing for batch operations for (const chunk of filterLazyChunked(largeDataset, { needsProcessing: true }, 1000)) { await api.batchUpdate(chunk); }

Benefits:

  • ๐Ÿš€ 500x faster for operations that don't need all results
  • ๐Ÿ’พ 100,000x less memory for large datasets
  • โšก Early exit optimization for existence checks
  • ๐Ÿ”„ Streaming support for async data sources
  • ๐Ÿ“ฆ Chunked processing for batch operations

See Lazy Evaluation Guide for complete documentation.


Memoization & Performance ๐Ÿ’พ

New in v5.2.0: Advanced multi-layer memoization strategy for maximum performance.

The library implements a sophisticated caching system with three layers:

  1. Result Cache - Caches complete filter results
  2. Predicate Cache - Memoizes compiled predicate functions
  3. Regex Cache - Caches compiled regex patterns

Basic Usage

import { filter, clearFilterCache, getFilterCacheStats } from '@mcabreradev/filter'; const largeDataset = [...]; // First call - processes data const results = filter(largeDataset, { age: { $gte: 18 } }, { enableCache: true }); // Second call - returns cached result instantly const sameResults = filter(largeDataset, { age: { $gte: 18 } }, { enableCache: true });

Performance Gains

Scenario Without Cache With Cache Speedup
Simple query (10K items) 5.3ms 0.01ms 530x
Regex pattern 12.1ms 0.02ms 605x
Complex nested 15.2ms 0.01ms 1520x

Real-World Example

const products = await fetchProducts(); const electronics = filter( products, { category: { $in: ['Electronics', 'Computers'] }, price: { $gte: 100, $lte: 2000 }, inStock: true, rating: { $gte: 4.0 } }, { enableCache: true } ); const electronicsAgain = filter( products, { category: { $in: ['Electronics', 'Computers'] }, price: { $gte: 100, $lte: 2000 }, inStock: true, rating: { $gte: 4.0 } }, { enableCache: true } );

Cache Management

// Get cache statistics const stats = getFilterCacheStats(); console.log(stats); // { hits: 150, misses: 10, size: 25, hitRate: 0.9375 } // Clear cache when data changes clearFilterCache(); // Memory management let data = [/* large dataset */]; filter(data, query, { enableCache: true }); data = null; // Cache will be garbage collected

When to Enable Caching

โœ… Enable for:

  • Large datasets (>1,000 items)
  • Repeated identical queries
  • Complex expressions with regex
  • Read-heavy workloads
  • Dashboard/analytics views

โŒ Disable for:

  • Frequently changing data
  • One-time queries
  • Memory-constrained environments
  • Unique expressions every time

Complete Example: Dashboard with Caching

import { filter, clearFilterCache } from '@mcabreradev/filter'; class ProductDashboard { private products: Product[]; constructor(products: Product[]) { this.products = products; } getElectronics() { return filter( this.products, { category: 'Electronics' }, { enableCache: true } ); } getHighRated() { return filter( this.products, { rating: { $gte: 4.5 } }, { enableCache: true } ); } refreshData(newProducts: Product[]) { this.products = newProducts; clearFilterCache(); } } const dashboard = new ProductDashboard(products); dashboard.getElectronics(); dashboard.getHighRated(); dashboard.getElectronics(); dashboard.getHighRated();

See Memoization Guide for complete documentation.


Visual Debugging (v5.5.0+) ๐Ÿ›

New in v5.5.0: Built-in debug mode with expression tree visualization, performance metrics, and condition tracking!

Basic Debug Mode

Enable debug mode to see how your filter expressions are evaluated:

import { filter } from '@mcabreradev/filter'; // Enable debug mode with config option filter(users, { city: 'Berlin' }, { debug: true }); // Console output: // โ”Œโ”€ Filter Debug Tree // โ”‚ Expression: {"city":"Berlin"} // โ”‚ Matched: 3/10 (30.0%) // โ”‚ Execution time: 0.42ms // โ””โ”€ โœ“ city = "Berlin"

Advanced Debugging Features

// Verbose mode - detailed evaluation info filter(users, { age: { $gte: 25 } }, { debug: true, verbose: true }); // Show execution timings filter(products, { premium: true }, { debug: true, showTimings: true }); // Colorized output (ANSI colors) filter(users, { city: 'Berlin' }, { debug: true, colorize: true }); // All options combined filter(users, { age: { $gte: 25 }, city: 'Berlin' }, { debug: true, verbose: true, showTimings: true, colorize: true });

Programmatic Access

Use filterDebug for programmatic access to debug information:

import { filterDebug } from '@mcabreradev/filter'; const result = filterDebug(users, { age: { $gte: 30 } }); console.log('Matched:', result.items.map(u => u.name)); console.log('Stats:', { matched: result.stats.matched, total: result.stats.total, percentage: result.stats.percentage, executionTime: result.stats.executionTime, conditionsEvaluated: result.stats.conditionsEvaluated }); // Access debug tree console.log('Debug Tree:', result.debug.tree);

Debug Complex Expressions

Visualize complex nested expressions:

filter(products, { $and: [ { category: 'Electronics' }, { inStock: true }, { $or: [ { rating: { $gte: 4.5 } }, { price: { $lt: 50 } } ] } ] }, { debug: true, verbose: true }); // Console output shows tree structure: // โ”Œโ”€ Filter Debug Tree // โ”‚ Expression: Complex nested query // โ”‚ Matched: 5/10 (50.0%) // โ”‚ Execution time: 1.23ms // โ”œโ”€ AND // โ”‚ โ”œโ”€ โœ“ category = "Electronics" // โ”‚ โ”œโ”€ โœ“ inStock = true // โ”‚ โ””โ”€ OR // โ”‚ โ”œโ”€ โœ“ rating >= 4.5 // โ”‚ โ””โ”€ โœ— price < 50 // โ””โ”€ Conditions evaluated: 8

Debug Options:

  • debug (boolean) - Enable debug mode
  • verbose (boolean) - Show detailed evaluation info
  • showTimings (boolean) - Display execution timings
  • colorize (boolean) - Use ANSI colors in output

Use Cases:

  • ๐Ÿ” Understanding complex filter logic
  • โšก Performance optimization
  • ๐Ÿ› Debugging unexpected results
  • ๐Ÿ“Š Analytics and monitoring
  • ๐Ÿงช Testing and validation

Configuration

Customize filter behavior with options:

import { filter } from '@mcabreradev/filter'; // Case-sensitive matching filter(users, 'ALICE', { caseSensitive: true }); // Increase max depth for nested objects filter(data, expression, { maxDepth: 5 }); // Enable caching for repeated queries filter(largeDataset, expression, { enableCache: true }); // Enable debug mode (v5.5.0+) filter(users, expression, { debug: true }); // Custom comparison logic filter(data, expression, { customComparator: (actual, expected) => actual === expected });

Available Options:

  • caseSensitive (boolean, default: false) - Case-sensitive string matching
  • maxDepth (number, default: 3, range: 1-10) - Max depth for nested objects
  • enableCache (boolean, default: false) - Enable result caching
  • debug (boolean, default: false) - Enable debug mode with tree visualization (v5.5.0+)
  • verbose (boolean, default: false) - Show detailed evaluation info in debug mode (v5.5.0+)
  • showTimings (boolean, default: false) - Display execution timings in debug mode (v5.5.0+)
  • colorize (boolean, default: false) - Use ANSI colors in debug output (v5.5.0+)
  • customComparator (function, optional) - Custom comparison function

TypeScript Support

Full TypeScript support with strict typing:

import { filter } from '@mcabreradev/filter'; import type { Expression, FilterOptions, ComparisonOperators } from '@mcabreradev/filter'; interface Product { id: number; name: string; price: number; category: string; } const products: Product[] = [...]; // Type-safe filtering const result = filter<Product>(products, { price: { $gte: 100 } }); // result is Product[] // Type-safe expressions const priceFilter: ComparisonOperators = { $gte: 100, $lte: 500 }; filter<Product>(products, { price: priceFilter });

Real-World Example

interface Product { id: number; name: string; price: number; category: string; brand: string; rating: number; inStock: boolean; tags: string[]; createdAt: Date; } const products: Product[] = [...]; // E-commerce: Find affordable, highly-rated electronics in stock const affordableElectronics = filter(products, { category: 'Electronics', price: { $lte: 1000 }, rating: { $gte: 4.5 }, inStock: { $eq: true } }); // Search: Products matching keyword with filters const searchResults = filter(products, { name: { $contains: 'laptop' }, brand: { $in: ['Apple', 'Dell', 'HP'] }, price: { $gte: 500, $lte: 2000 } }); // Analytics: Recent high-value orders const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); const recentHighValue = filter(orders, { createdAt: { $gte: thirtyDaysAgo }, amount: { $gte: 1000 }, status: { $in: ['completed', 'shipped'] } });

Performance

Filter is optimized for performance:

  • Operators use early exit strategies for fast evaluation
  • Regex patterns are compiled and cached
  • Optional caching for repeated queries on large datasets (530x-1520x faster)
  • Lazy evaluation for efficient large dataset processing (500x faster)
  • Type guards for fast type checking
// โœ… Fast: Operators with early exit filter(data, { age: { $gte: 18 } }); // โœ… Fast with caching for repeated queries filter(largeData, expression, { enableCache: true }); // โœ… Fast with lazy evaluation for large datasets const result = filterFirst(millionRecords, { active: true }, 100); // โš ๏ธ Slower: Complex predicates (but more flexible) filter(data, (item) => complexCalculation(item));

For performance optimization tips, see Performance Guide.


Documentation

๐Ÿ“– Complete Documentation

  • Complete Wiki - Complete documentation with 150+ examples, API reference, TypeScript guide, real-world use cases, FAQ, and troubleshooting
  • Framework Integrations - Complete guide for React, Vue, and Svelte integrations
  • Operators Guide - Detailed guide for all 30+ MongoDB-style operators with examples and advanced regex patterns
  • Geospatial Operators - Complete guide for location-based filtering with $near, $geoBox, $geoPolygon
  • Date/Time Operators - Complete guide for temporal filtering with $recent, $upcoming, $dayOfWeek, $age
  • Lazy Evaluation - Comprehensive guide to lazy evaluation for efficient large dataset processing
  • Logical Operators - Advanced patterns and complex queries with $and, $or, $not
  • Performance Benchmarks - Detailed performance metrics and optimization strategies
  • Migration Guide - Migration guide from v3.x or native Array.filter()
  • Examples - Real-world usage examples and code samples

๐ŸŽฏ Quick Links


Migration from v3.x

Good news: v5.x is 100% backward compatible! All v3.x code continues to work.

// โœ… All v3.x syntax still works filter(data, 'string'); filter(data, { prop: 'value' }); filter(data, (item) => true); filter(data, '%pattern%'); // โœ… New in v5.x filter(data, { age: { $gte: 18 } }); filter(data, expression, { caseSensitive: true }); filter(data, expression, { enableCache: true });

What's New in v5.x:

  • v5.5.0: Array OR syntax, visual debugging, interactive playground
  • v5.4.0: Framework integrations (React, Vue, Svelte)
  • v5.3.0: Initial framework support
  • v5.2.0: Enhanced memoization, logical operators ($and, $or, $not), regex operators
  • v5.1.0: Lazy evaluation with generators
  • v5.0.0: 18+ MongoDB-style operators, configuration API, runtime validation

See Migration Guide for detailed migration guide.


API Overview

// Main filter function filter<T>(array: T[], expression: Expression<T>, options?: FilterOptions): T[] // Lazy evaluation functions filterLazy<T>(array: T[], expression: Expression<T>, options?: FilterOptions): IterableIterator<T> filterFirst<T>(array: T[], expression: Expression<T>, count: number, options?: FilterOptions): T[] filterExists<T>(array: T[], expression: Expression<T>, options?: FilterOptions): boolean filterCount<T>(array: T[], expression: Expression<T>, options?: FilterOptions): number // Validation functions validateExpression(expression: unknown): Expression<T> validateOptions(options: unknown): FilterOptions // Cache management clearFilterCache(): void getFilterCacheStats(): { hits: number; misses: number; size: number; hitRate: number } // Configuration mergeConfig(options?: FilterOptions): FilterConfig createFilterConfig(options?: FilterOptions): FilterConfig // Geospatial utilities calculateDistance(p1: GeoPoint, p2: GeoPoint): number isValidGeoPoint(point: unknown): point is GeoPoint evaluateNear(point: GeoPoint, query: NearQuery): boolean evaluateGeoBox(point: GeoPoint, box: BoundingBox): boolean evaluateGeoPolygon(point: GeoPoint, query: PolygonQuery): boolean // Framework integrations useFilter<T>(data: T[], expression: Expression<T>, options?: FilterOptions) // React useFilter<T>(data: Ref<T[]>, expression: Ref<Expression<T>>, options?: FilterOptions) // Vue filterStore<T>(data: Writable<T[]>, expression: Writable<Expression<T>>, options?: FilterOptions) // Svelte

For complete API reference, see API Reference.


Browser Support

Works in all modern browsers and Node.js:

  • Node.js: >= 20
  • Browsers: Chrome, Firefox, Safari, Edge (latest versions)
  • TypeScript: >= 5.0
  • Module Systems: ESM, CommonJS

Contributing

We welcome contributions! Please read our Contributing Guide for details on:

  • Development setup and workflow
  • Testing requirements
  • Coding standards
  • Pull request process

Ways to Contribute:

  • Report bugs or request features via GitHub Issues
  • Submit pull requests with bug fixes or new features
  • Improve documentation
  • Share your use cases and examples

For detailed guidelines, see CONTRIBUTING.md


Testing

# Run tests pnpm test # Watch mode pnpm test:watch # Coverage report pnpm test:coverage # Type checking pnpm typecheck

The library has 270+ tests with comprehensive coverage of all features.


Changelog

v5.6.0 (Current)

  • ๐ŸŒ Geospatial Operators: Location-based filtering with $near, $geoBox, $geoPolygon
  • ๐Ÿ“ Distance Calculation: Spherical law of cosines for accurate distance measurement
  • ๐Ÿ—บ๏ธ Spatial Queries: Proximity search, bounding box, and polygon containment
  • ๐Ÿ”’ Coordinate Validation: Automatic validation of lat/lng coordinates
  • โšก Performance Optimized: Fast algorithms for all geospatial operations
  • ๐Ÿ“š Complete geospatial documentation and examples
  • ๐Ÿ“… Date/Time Operators: Temporal filtering with $recent, $upcoming, $dayOfWeek, $timeOfDay, $age
  • โฐ Relative Time Filtering: Filter by last/next N days/hours/minutes
  • ๐Ÿ—“๏ธ Day-of-Week Filtering: Filter by specific days (Monday-Sunday)
  • ๐Ÿ• Time-of-Day Filtering: Filter by hour ranges (0-23)
  • ๐ŸŽ‚ Age Calculation: Calculate age in years/months/days with min/max ranges
  • ๐Ÿ“Š Weekday/Weekend Support: $isWeekday and $isWeekend operators
  • ๐Ÿ”’ Full TypeScript Support: Context-aware autocomplete for Date properties
  • ๐Ÿš€ Zero Dependencies: Uses native Date API
  • ๐Ÿ“š Complete datetime operators documentation and examples
  • โœ… 90 new tests (613 total tests)

v5.5.1

  • ๐Ÿ› Bug fixes and stability improvements
  • ๐Ÿ“š Documentation updates
  • ๐Ÿ”ง Build optimizations

v5.5.0

  • ๐ŸŽจ Array OR Syntax: Intuitive array-based OR filtering ({ city: ['Berlin', 'Paris'] })
  • ๐Ÿ› Visual Debugging: Built-in debug mode with expression tree visualization
  • ๐ŸŽฎ Interactive Playground: New online playground for testing filters
  • ๐Ÿ“Š Debug Analytics: Performance metrics and condition evaluation tracking
  • ๐ŸŽจ Colorized Output: ANSI color support for debug tree visualization
  • โšก Performance improvements for array operations

v5.4.0

  • ๐ŸŽจ Framework Integrations: React, Vue, and Svelte support
  • ๐Ÿช React Hooks: useFilter, useFilteredState, useDebouncedFilter, usePaginatedFilter
  • ๐Ÿ”„ Vue Composables: Full Composition API support with reactive refs
  • ๐Ÿ“ฆ Svelte Stores: Reactive store-based filtering
  • ๐Ÿ“š Comprehensive framework documentation
  • โœ… 100% test coverage for all integrations
  • ๐Ÿ”’ TypeScript generics for type safety
  • ๐ŸŒ SSR compatibility (Next.js, Nuxt, SvelteKit)

v5.3.0

  • ๐ŸŽจ Initial framework integration support
  • ๐Ÿช React hooks implementation
  • ๐Ÿ”„ Vue composables implementation
  • ๐Ÿ“ฆ Svelte stores implementation

v5.2.0

  • ๐Ÿ’พ Enhanced Memoization: Multi-layer caching (530x faster)
  • ๐Ÿ”€ Logical Operators: $and, $or, $not for complex queries
  • ๐Ÿ“ Regex Operators: $regex and $match for pattern matching
  • ๐Ÿš€ Performance optimizations

v5.1.0

  • ๐Ÿ’จ Lazy Evaluation: filterLazy, filterFirst for efficient processing
  • ๐Ÿ”„ Generator-based filtering
  • โšก Early exit optimization

v5.0.0

  • โœจ Added 18+ MongoDB-style operators
  • โš™๏ธ Configuration API with 4 options
  • โœ… Runtime validation with Zod
  • ๐Ÿš€ Performance optimizations
  • ๐Ÿ“˜ Enhanced TypeScript support
  • ๐Ÿงช 270+ tests
  • ๐Ÿ“ Reorganized documentation into /docs directory

See Migration Guide for detailed changelog and migration guide.


License

MIT License - see LICENSE.md for details.

Copyright (c) 2025 Miguelangel Cabrera


Credits

Author: Miguelรกngel Cabrera Repository: github.com/mcabreradev/filter

Inspired by MongoDB query syntax, SQL wildcards, and functional programming patterns.


Support


Made with โค๏ธ for the JavaScript/TypeScript community

About

A powerful, zero-dependency filtering library that brings MongoDB-style operators, SQL wildcards, and intelligent autocomplete to TypeScript arrays. Think of it as Array.filter() on steroids! ๐Ÿ’ช

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors 5