@smakss/search
Advanced tools
Comparing version 2.0.0-beta.1 to 2.0.0-beta.2
@@ -1,37 +0,1 @@ | ||
import { SearchItem } from './types'; | ||
/** | ||
* The SearchOptions interface represents the structure for search configuration. | ||
*/ | ||
interface SearchOptions { | ||
searchText: string; | ||
searchItems: SearchItem[]; | ||
keys: string[]; | ||
include: boolean; | ||
exact: boolean; | ||
} | ||
/** | ||
* Performs a search on an array of items or nested arrays/objects and returns the matched items. | ||
* | ||
* @param {Partial<SearchOptions<T>>} options - An object containing search parameters. | ||
* @param {string} options.searchText - The text to search for. | ||
* @param {Array<SearchItem<T>>} options.searchItems - The items to search through. | ||
* @param {string[]} options.keys - Specific keys to include or exclude in the search. | ||
* @param {boolean} options.include - Flag to determine if the keys should be included or excluded. | ||
* @param {boolean} options.exact - Flag to determine if the search should be for an exact match. | ||
* @returns {Array<SearchItem<T>>} A filtered array of items that match the search criteria. | ||
* @template T - The generic type parameter for the items being searched. | ||
* | ||
* @example | ||
* // Assuming a predefined SearchItem type | ||
* const items = [{ name: 'John Doe' }, { name: 'Jane Doe' }]; | ||
* const results = search({ | ||
* searchText: 'Jane', | ||
* searchItems: items, | ||
* keys: ['name'], | ||
* include: true, | ||
* exact: false | ||
* }); | ||
* // results will be [{ name: 'Jane Doe' }] | ||
*/ | ||
declare function search({ searchText, searchItems, keys, include, exact }: Partial<SearchOptions>): SearchItem[]; | ||
export default search; | ||
export { default } from './search'; |
@@ -6,57 +6,33 @@ 'use strict'; | ||
/** | ||
* Checks if a given value matches a regular expression. | ||
* Determines whether a given key is included in the search based on the include parameter and the keys provided. | ||
* | ||
* @param {unknown} value - The value to test against the regular expression. | ||
* @param {RegExp} regex - The regular expression to match. | ||
* @returns {boolean} True if the value is a string and matches the regex, false otherwise. | ||
* @param {string} key - The key to check. | ||
* @param {string[]} keys - The list of keys to consider in the search. | ||
* @param {boolean} include - Flag determining if the keys should be included or excluded from the search. | ||
* @returns {boolean} - True if the key is included in the search, false otherwise. | ||
* | ||
* @example | ||
* // returns true | ||
* matchesRegex('hello', /hello/); | ||
* | ||
* @example | ||
* // returns false | ||
* matchesRegex(123, /hello/); | ||
* // Check if 'name' is included in a search considering only 'name' and 'age': | ||
* console.log(isKeyIncluded('name', ['name', 'age'], true)); // Output: true | ||
* console.log(isKeyIncluded('address', ['name', 'age'], true)); // Output: false | ||
*/ | ||
function matchesRegex(value, regex) { | ||
return typeof value === 'string' && regex.test(value); | ||
} | ||
/** | ||
* Determines whether a key should be included in the search based on the include parameter. | ||
* | ||
* @param {string[]} keys - An array of keys to include or exclude. | ||
* @param {string} key - The current key to check. | ||
* @param {boolean} include - Whether to include or exclude the keys array. | ||
* @returns {boolean} True if the key should be included, false otherwise. | ||
* | ||
* @example | ||
* // returns true | ||
* shouldIncludeKey(['name', 'age'], 'name', true); | ||
* | ||
* @example | ||
* // returns false | ||
* shouldIncludeKey(['name', 'age'], 'location', true); | ||
*/ | ||
function shouldIncludeKey(key, keys, include) { | ||
function isKeyIncluded(key, keys, include) { | ||
return include ? keys.includes(key) : !keys.includes(key); | ||
} | ||
/** | ||
* Adds an item to the filtered list if it is not already present. | ||
* Adds a search item to the results if it's not already included. | ||
* | ||
* @param {SearchItem<T>[]} filtered - The array to which the item will be added if it is unique. | ||
* @param {SearchItem<T>} item - The item to add if it is not already present in the array. | ||
* @param {SearchItem[]} results - The current list of search results. | ||
* @param {SearchItem} item - The item to potentially add to the results. | ||
* | ||
* @example | ||
* // filtered contains [{name: 'John'}, {name: 'Jane'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'Jane'}); | ||
* | ||
* @example | ||
* // filtered remains unchanged [{name: 'John'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'John'}); | ||
* // Example usage of addUniqueMatch | ||
* const results: SearchItem[] = []; | ||
* const itemToAdd: SearchItem = { name: 'John', age: 30 }; | ||
* addUniqueMatch(results, itemToAdd); | ||
* console.log(results); // Output: [{ name: 'John', age: 30 }] | ||
*/ | ||
function addIfUnique(filtered, item) { | ||
if (!filtered.some((el) => Object.is(el, item))) { | ||
filtered.push(item); | ||
function addUniqueMatch(results, item) { | ||
if (!results.includes(item)) { | ||
results.push(item); | ||
} | ||
@@ -66,27 +42,27 @@ } | ||
/** | ||
* Searches through the properties of an object and adds matches to a filtered list. | ||
* If a property value is an array, it will recursively search through the array as well. | ||
* Searches for matches within an object based on a regex pattern. | ||
* If a match is found within the specified keys, it adds the object to the results. | ||
* | ||
* @param {SearchItem<T>} obj - The object to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within. | ||
* @param {SearchItem} object - The object to search within. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the property values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against the object values. | ||
* @param {SearchItem[]} results - The array to store matching objects. | ||
* | ||
* @example | ||
* const obj = { name: 'John', age: 30 }; | ||
* const filtered = []; | ||
* searchInObject(obj, filtered, ['name'], true, /John/); | ||
* // filtered now contains [{ name: 'John', age: 30 }] | ||
* // Define an object to search | ||
* const person = { name: "John", lastName: "Doe" }; | ||
* const results = []; | ||
* | ||
* // Search within the object for the name 'John' | ||
* searchWithinObject(person, ['name'], true, /John/i, results); | ||
* | ||
* // results will contain the person object | ||
* console.log(results); // [{ name: "John", lastName: "Doe" }] | ||
*/ | ||
function searchInObject(obj, filtered, keys, include, regex) { | ||
for (const [key, value] of Object.entries(obj)) { | ||
if (shouldIncludeKey(key, keys, include)) { | ||
if (typeof value === 'string' && matchesRegex(value, regex)) { | ||
addIfUnique(filtered, obj); | ||
} | ||
else if (Array.isArray(value)) { | ||
searchInArray(value, filtered, keys, include, regex); | ||
} | ||
function searchWithinObject(object, keys, include, regex, results) { | ||
for (const key of Object.keys(object)) { | ||
if (isKeyIncluded(key, keys, include) && regex.test(String(object[key]))) { | ||
addUniqueMatch(results, object); | ||
break; | ||
} | ||
@@ -96,75 +72,77 @@ } | ||
/** | ||
* Searches through an array of items, adding matches to a filtered list. | ||
* If an item is an array itself, it will recursively search through that array as well. | ||
* Recursively searches through items for matches based on a regex pattern. | ||
* It handles both arrays and individual objects. | ||
* | ||
* @param {Array<SearchItem<T>>} arr - The array to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within if the items are objects. | ||
* @param {SearchItem | SearchItem[]} items - The items to search through. Can be a single item or an array of items. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the item values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against item values. | ||
* @param {SearchItem[]} results - The array to store matching items. | ||
* | ||
* @example | ||
* const items = [{ name: 'John' }, { name: 'Jane' }]; | ||
* const filtered = []; | ||
* searchInArray(items, filtered, ['name'], true, /Jane/); | ||
* // filtered now contains [{ name: 'Jane' }] | ||
* // Define a list of objects to search | ||
* const people = [ | ||
* { name: "John", lastName: "Doe" }, | ||
* { name: "Jane", lastName: "Doe" }, | ||
* ]; | ||
* const searchResults = []; | ||
* | ||
* // Recursively search for the term 'doe' in the list of people | ||
* recursiveSearch(people, ['lastName'], true, /doe/i, searchResults); | ||
* | ||
* // searchResults will contain both person objects | ||
* console.log(searchResults); // [{ name: "John", lastName: "Doe" }, { name: "Jane", lastName: "Doe" }] | ||
*/ | ||
function searchInArray(arr, filtered, keys, include, regex) { | ||
for (const item of arr) { | ||
if (typeof item === 'string' && matchesRegex(item, regex)) { | ||
addIfUnique(filtered, item); | ||
function recursiveSearch(items, keys, include, regex, results) { | ||
if (Array.isArray(items)) { | ||
for (const item of items) { | ||
recursiveSearch(item, keys, include, regex, results); | ||
} | ||
else if (Array.isArray(item)) { | ||
searchInArray(item, filtered, keys, include, regex); | ||
} | ||
else if (typeof item === 'object' && item !== null) { | ||
searchInObject(item, filtered, keys, include, regex); | ||
} | ||
} | ||
else if (typeof items === 'object' && items !== null) { | ||
searchWithinObject(items, keys, include, regex, results); | ||
} | ||
else if (regex.test(String(items))) { | ||
addUniqueMatch(results, [items]); | ||
} | ||
} | ||
/** | ||
* Performs a search on an array of items or nested arrays/objects and returns the matched items. | ||
* Searches for items within a collection that match the given search text. | ||
* | ||
* @param {Partial<SearchOptions<T>>} options - An object containing search parameters. | ||
* @param {string} options.searchText - The text to search for. | ||
* @param {Array<SearchItem<T>>} options.searchItems - The items to search through. | ||
* @param {string[]} options.keys - Specific keys to include or exclude in the search. | ||
* @param {boolean} options.include - Flag to determine if the keys should be included or excluded. | ||
* @param {boolean} options.exact - Flag to determine if the search should be for an exact match. | ||
* @returns {Array<SearchItem<T>>} A filtered array of items that match the search criteria. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {Partial<SearchOptions>} options - The search parameters including searchText, searchItems, keys to search in, | ||
* whether to include keys and if the search is exact. | ||
* @returns {SearchItem[]} The matched items as an array. | ||
* | ||
* @example | ||
* // Assuming a predefined SearchItem type | ||
* const items = [{ name: 'John Doe' }, { name: 'Jane Doe' }]; | ||
* const results = search({ | ||
* searchText: 'Jane', | ||
* searchItems: items, | ||
* keys: ['name'], | ||
* // Define a list of objects to search | ||
* const people = [ | ||
* { name: "John", lastName: "Doe" }, | ||
* { name: "Jane", lastName: "Smith" }, | ||
* ]; | ||
* | ||
* // Options for searching | ||
* const options = { | ||
* searchText: "doe", | ||
* searchItems: people, | ||
* keys: ['lastName'], | ||
* include: true, | ||
* exact: false | ||
* }); | ||
* // results will be [{ name: 'Jane Doe' }] | ||
* }; | ||
* | ||
* // Perform the search | ||
* const found = search(options); | ||
* | ||
* // found will contain the object with lastName 'Doe' | ||
* console.log(found); // [{ name: "John", lastName: "Doe" }] | ||
*/ | ||
function search({ searchText = '', searchItems = [], keys = [], include = true, exact = false }) { | ||
const regex = exact | ||
? new RegExp(`^${searchText}$`, 'i') | ||
: new RegExp(searchText, 'i'); | ||
const filtered = []; | ||
searchItems.forEach((item) => { | ||
if (typeof item === 'string') { | ||
if (matchesRegex(item, regex)) { | ||
addIfUnique(filtered, item); | ||
} | ||
} | ||
else if (Array.isArray(item)) { | ||
searchInArray(item, filtered, keys, include, regex); | ||
} | ||
else if (typeof item === 'object' && item !== null) { | ||
searchInObject(item, filtered, keys, include, regex); | ||
} | ||
}); | ||
return filtered; | ||
const regex = new RegExp(exact ? `^${searchText}$` : searchText, 'i'); | ||
const results = []; | ||
const preparedItems = Array.isArray(searchItems) | ||
? searchItems | ||
: [searchItems]; | ||
const preparedKeys = keys.length > 0 ? keys : Object.keys(preparedItems[0] || {}); | ||
recursiveSearch(preparedItems, preparedKeys, include, regex, results); | ||
return results; | ||
} | ||
@@ -171,0 +149,0 @@ |
import { SearchItem } from './types'; | ||
/** | ||
* Searches through the properties of an object and adds matches to a filtered list. | ||
* If a property value is an array, it will recursively search through the array as well. | ||
* Searches for matches within an object based on a regex pattern. | ||
* If a match is found within the specified keys, it adds the object to the results. | ||
* | ||
* @param {SearchItem<T>} obj - The object to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within. | ||
* @param {SearchItem} object - The object to search within. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the property values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against the object values. | ||
* @param {SearchItem[]} results - The array to store matching objects. | ||
* | ||
* @example | ||
* const obj = { name: 'John', age: 30 }; | ||
* const filtered = []; | ||
* searchInObject(obj, filtered, ['name'], true, /John/); | ||
* // filtered now contains [{ name: 'John', age: 30 }] | ||
* // Define an object to search | ||
* const person = { name: "John", lastName: "Doe" }; | ||
* const results = []; | ||
* | ||
* // Search within the object for the name 'John' | ||
* searchWithinObject(person, ['name'], true, /John/i, results); | ||
* | ||
* // results will contain the person object | ||
* console.log(results); // [{ name: "John", lastName: "Doe" }] | ||
*/ | ||
export declare function searchInObject(obj: SearchItem, filtered: SearchItem[], keys: string[], include: boolean, regex: RegExp): void; | ||
export declare function searchWithinObject(object: SearchItem, keys: string[], include: boolean, regex: RegExp, results: SearchItem[]): void; | ||
/** | ||
* Searches through an array of items, adding matches to a filtered list. | ||
* If an item is an array itself, it will recursively search through that array as well. | ||
* Recursively searches through items for matches based on a regex pattern. | ||
* It handles both arrays and individual objects. | ||
* | ||
* @param {Array<SearchItem<T>>} arr - The array to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within if the items are objects. | ||
* @param {SearchItem | SearchItem[]} items - The items to search through. Can be a single item or an array of items. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the item values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against item values. | ||
* @param {SearchItem[]} results - The array to store matching items. | ||
* | ||
* @example | ||
* const items = [{ name: 'John' }, { name: 'Jane' }]; | ||
* const filtered = []; | ||
* searchInArray(items, filtered, ['name'], true, /Jane/); | ||
* // filtered now contains [{ name: 'Jane' }] | ||
* // Define a list of objects to search | ||
* const people = [ | ||
* { name: "John", lastName: "Doe" }, | ||
* { name: "Jane", lastName: "Doe" }, | ||
* ]; | ||
* const searchResults = []; | ||
* | ||
* // Recursively search for the term 'doe' in the list of people | ||
* recursiveSearch(people, ['lastName'], true, /doe/i, searchResults); | ||
* | ||
* // searchResults will contain both person objects | ||
* console.log(searchResults); // [{ name: "John", lastName: "Doe" }, { name: "Jane", lastName: "Doe" }] | ||
*/ | ||
export declare function searchInArray(arr: SearchItem[], filtered: SearchItem[], keys: string[], include: boolean, regex: RegExp): void; | ||
export declare function recursiveSearch(items: SearchItem | SearchItem[], keys: string[], include: boolean, regex: RegExp, results: SearchItem[]): void; |
@@ -1,1 +0,30 @@ | ||
export type SearchItem = Record<string, unknown>; | ||
/** | ||
* Represents a searchable item as a key-value record. | ||
* Any value type is allowed since the search functionality will cast to string for comparison. | ||
* | ||
* @example | ||
* // A sample SearchItem could look like this: | ||
* const item: SearchItem = { name: "John", age: 30, address: "123 Main St" }; | ||
*/ | ||
export type SearchItem = Record<string, any>; | ||
/** | ||
* Describes the options for the search function including the text to search for, the items to search within, | ||
* the keys in the items to consider, whether to include or exclude the specified keys, and whether the search should match exactly. | ||
* | ||
* @example | ||
* // An example of SearchOptions usage: | ||
* const options: SearchOptions = { | ||
* searchText: 'John', | ||
* searchItems: [{ name: 'John Doe', age: 28 }, { name: 'Jane Doe', age: 32 }], | ||
* keys: ['name'], | ||
* include: true, | ||
* exact: false | ||
* }; | ||
*/ | ||
export interface SearchOptions { | ||
searchText: string; | ||
searchItems: SearchItem | SearchItem[]; | ||
keys: string[]; | ||
include: boolean; | ||
exact: boolean; | ||
} |
import { SearchItem } from './types'; | ||
/** | ||
* Checks if a given value matches a regular expression. | ||
* Determines whether a given key is included in the search based on the include parameter and the keys provided. | ||
* | ||
* @param {unknown} value - The value to test against the regular expression. | ||
* @param {RegExp} regex - The regular expression to match. | ||
* @returns {boolean} True if the value is a string and matches the regex, false otherwise. | ||
* @param {string} key - The key to check. | ||
* @param {string[]} keys - The list of keys to consider in the search. | ||
* @param {boolean} include - Flag determining if the keys should be included or excluded from the search. | ||
* @returns {boolean} - True if the key is included in the search, false otherwise. | ||
* | ||
* @example | ||
* // returns true | ||
* matchesRegex('hello', /hello/); | ||
* | ||
* @example | ||
* // returns false | ||
* matchesRegex(123, /hello/); | ||
* // Check if 'name' is included in a search considering only 'name' and 'age': | ||
* console.log(isKeyIncluded('name', ['name', 'age'], true)); // Output: true | ||
* console.log(isKeyIncluded('address', ['name', 'age'], true)); // Output: false | ||
*/ | ||
export declare function matchesRegex(value: unknown, regex: RegExp): boolean; | ||
export declare function isKeyIncluded(key: string, keys: string[], include: boolean): boolean; | ||
/** | ||
* Determines whether a key should be included in the search based on the include parameter. | ||
* Adds a search item to the results if it's not already included. | ||
* | ||
* @param {string[]} keys - An array of keys to include or exclude. | ||
* @param {string} key - The current key to check. | ||
* @param {boolean} include - Whether to include or exclude the keys array. | ||
* @returns {boolean} True if the key should be included, false otherwise. | ||
* @param {SearchItem[]} results - The current list of search results. | ||
* @param {SearchItem} item - The item to potentially add to the results. | ||
* | ||
* @example | ||
* // returns true | ||
* shouldIncludeKey(['name', 'age'], 'name', true); | ||
* | ||
* @example | ||
* // returns false | ||
* shouldIncludeKey(['name', 'age'], 'location', true); | ||
* // Example usage of addUniqueMatch | ||
* const results: SearchItem[] = []; | ||
* const itemToAdd: SearchItem = { name: 'John', age: 30 }; | ||
* addUniqueMatch(results, itemToAdd); | ||
* console.log(results); // Output: [{ name: 'John', age: 30 }] | ||
*/ | ||
export declare function shouldIncludeKey(key: string, keys: string[], include: boolean): boolean; | ||
/** | ||
* Adds an item to the filtered list if it is not already present. | ||
* | ||
* @param {SearchItem<T>[]} filtered - The array to which the item will be added if it is unique. | ||
* @param {SearchItem<T>} item - The item to add if it is not already present in the array. | ||
* | ||
* @example | ||
* // filtered contains [{name: 'John'}, {name: 'Jane'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'Jane'}); | ||
* | ||
* @example | ||
* // filtered remains unchanged [{name: 'John'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'John'}); | ||
*/ | ||
export declare function addIfUnique(filtered: SearchItem[], item: SearchItem): void; | ||
export declare function addUniqueMatch(results: SearchItem[], item: SearchItem): void; |
@@ -1,37 +0,1 @@ | ||
import { SearchItem } from './types'; | ||
/** | ||
* The SearchOptions interface represents the structure for search configuration. | ||
*/ | ||
interface SearchOptions { | ||
searchText: string; | ||
searchItems: SearchItem[]; | ||
keys: string[]; | ||
include: boolean; | ||
exact: boolean; | ||
} | ||
/** | ||
* Performs a search on an array of items or nested arrays/objects and returns the matched items. | ||
* | ||
* @param {Partial<SearchOptions<T>>} options - An object containing search parameters. | ||
* @param {string} options.searchText - The text to search for. | ||
* @param {Array<SearchItem<T>>} options.searchItems - The items to search through. | ||
* @param {string[]} options.keys - Specific keys to include or exclude in the search. | ||
* @param {boolean} options.include - Flag to determine if the keys should be included or excluded. | ||
* @param {boolean} options.exact - Flag to determine if the search should be for an exact match. | ||
* @returns {Array<SearchItem<T>>} A filtered array of items that match the search criteria. | ||
* @template T - The generic type parameter for the items being searched. | ||
* | ||
* @example | ||
* // Assuming a predefined SearchItem type | ||
* const items = [{ name: 'John Doe' }, { name: 'Jane Doe' }]; | ||
* const results = search({ | ||
* searchText: 'Jane', | ||
* searchItems: items, | ||
* keys: ['name'], | ||
* include: true, | ||
* exact: false | ||
* }); | ||
* // results will be [{ name: 'Jane Doe' }] | ||
*/ | ||
declare function search({ searchText, searchItems, keys, include, exact }: Partial<SearchOptions>): SearchItem[]; | ||
export default search; | ||
export { default } from './search'; |
/** | ||
* Checks if a given value matches a regular expression. | ||
* Determines whether a given key is included in the search based on the include parameter and the keys provided. | ||
* | ||
* @param {unknown} value - The value to test against the regular expression. | ||
* @param {RegExp} regex - The regular expression to match. | ||
* @returns {boolean} True if the value is a string and matches the regex, false otherwise. | ||
* @param {string} key - The key to check. | ||
* @param {string[]} keys - The list of keys to consider in the search. | ||
* @param {boolean} include - Flag determining if the keys should be included or excluded from the search. | ||
* @returns {boolean} - True if the key is included in the search, false otherwise. | ||
* | ||
* @example | ||
* // returns true | ||
* matchesRegex('hello', /hello/); | ||
* | ||
* @example | ||
* // returns false | ||
* matchesRegex(123, /hello/); | ||
* // Check if 'name' is included in a search considering only 'name' and 'age': | ||
* console.log(isKeyIncluded('name', ['name', 'age'], true)); // Output: true | ||
* console.log(isKeyIncluded('address', ['name', 'age'], true)); // Output: false | ||
*/ | ||
function matchesRegex(value, regex) { | ||
return typeof value === 'string' && regex.test(value); | ||
} | ||
/** | ||
* Determines whether a key should be included in the search based on the include parameter. | ||
* | ||
* @param {string[]} keys - An array of keys to include or exclude. | ||
* @param {string} key - The current key to check. | ||
* @param {boolean} include - Whether to include or exclude the keys array. | ||
* @returns {boolean} True if the key should be included, false otherwise. | ||
* | ||
* @example | ||
* // returns true | ||
* shouldIncludeKey(['name', 'age'], 'name', true); | ||
* | ||
* @example | ||
* // returns false | ||
* shouldIncludeKey(['name', 'age'], 'location', true); | ||
*/ | ||
function shouldIncludeKey(key, keys, include) { | ||
function isKeyIncluded(key, keys, include) { | ||
return include ? keys.includes(key) : !keys.includes(key); | ||
} | ||
/** | ||
* Adds an item to the filtered list if it is not already present. | ||
* Adds a search item to the results if it's not already included. | ||
* | ||
* @param {SearchItem<T>[]} filtered - The array to which the item will be added if it is unique. | ||
* @param {SearchItem<T>} item - The item to add if it is not already present in the array. | ||
* @param {SearchItem[]} results - The current list of search results. | ||
* @param {SearchItem} item - The item to potentially add to the results. | ||
* | ||
* @example | ||
* // filtered contains [{name: 'John'}, {name: 'Jane'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'Jane'}); | ||
* | ||
* @example | ||
* // filtered remains unchanged [{name: 'John'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'John'}); | ||
* // Example usage of addUniqueMatch | ||
* const results: SearchItem[] = []; | ||
* const itemToAdd: SearchItem = { name: 'John', age: 30 }; | ||
* addUniqueMatch(results, itemToAdd); | ||
* console.log(results); // Output: [{ name: 'John', age: 30 }] | ||
*/ | ||
function addIfUnique(filtered, item) { | ||
if (!filtered.some((el) => Object.is(el, item))) { | ||
filtered.push(item); | ||
function addUniqueMatch(results, item) { | ||
if (!results.includes(item)) { | ||
results.push(item); | ||
} | ||
@@ -61,27 +37,27 @@ } | ||
/** | ||
* Searches through the properties of an object and adds matches to a filtered list. | ||
* If a property value is an array, it will recursively search through the array as well. | ||
* Searches for matches within an object based on a regex pattern. | ||
* If a match is found within the specified keys, it adds the object to the results. | ||
* | ||
* @param {SearchItem<T>} obj - The object to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within. | ||
* @param {SearchItem} object - The object to search within. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the property values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against the object values. | ||
* @param {SearchItem[]} results - The array to store matching objects. | ||
* | ||
* @example | ||
* const obj = { name: 'John', age: 30 }; | ||
* const filtered = []; | ||
* searchInObject(obj, filtered, ['name'], true, /John/); | ||
* // filtered now contains [{ name: 'John', age: 30 }] | ||
* // Define an object to search | ||
* const person = { name: "John", lastName: "Doe" }; | ||
* const results = []; | ||
* | ||
* // Search within the object for the name 'John' | ||
* searchWithinObject(person, ['name'], true, /John/i, results); | ||
* | ||
* // results will contain the person object | ||
* console.log(results); // [{ name: "John", lastName: "Doe" }] | ||
*/ | ||
function searchInObject(obj, filtered, keys, include, regex) { | ||
for (const [key, value] of Object.entries(obj)) { | ||
if (shouldIncludeKey(key, keys, include)) { | ||
if (typeof value === 'string' && matchesRegex(value, regex)) { | ||
addIfUnique(filtered, obj); | ||
} | ||
else if (Array.isArray(value)) { | ||
searchInArray(value, filtered, keys, include, regex); | ||
} | ||
function searchWithinObject(object, keys, include, regex, results) { | ||
for (const key of Object.keys(object)) { | ||
if (isKeyIncluded(key, keys, include) && regex.test(String(object[key]))) { | ||
addUniqueMatch(results, object); | ||
break; | ||
} | ||
@@ -91,75 +67,77 @@ } | ||
/** | ||
* Searches through an array of items, adding matches to a filtered list. | ||
* If an item is an array itself, it will recursively search through that array as well. | ||
* Recursively searches through items for matches based on a regex pattern. | ||
* It handles both arrays and individual objects. | ||
* | ||
* @param {Array<SearchItem<T>>} arr - The array to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within if the items are objects. | ||
* @param {SearchItem | SearchItem[]} items - The items to search through. Can be a single item or an array of items. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the item values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against item values. | ||
* @param {SearchItem[]} results - The array to store matching items. | ||
* | ||
* @example | ||
* const items = [{ name: 'John' }, { name: 'Jane' }]; | ||
* const filtered = []; | ||
* searchInArray(items, filtered, ['name'], true, /Jane/); | ||
* // filtered now contains [{ name: 'Jane' }] | ||
* // Define a list of objects to search | ||
* const people = [ | ||
* { name: "John", lastName: "Doe" }, | ||
* { name: "Jane", lastName: "Doe" }, | ||
* ]; | ||
* const searchResults = []; | ||
* | ||
* // Recursively search for the term 'doe' in the list of people | ||
* recursiveSearch(people, ['lastName'], true, /doe/i, searchResults); | ||
* | ||
* // searchResults will contain both person objects | ||
* console.log(searchResults); // [{ name: "John", lastName: "Doe" }, { name: "Jane", lastName: "Doe" }] | ||
*/ | ||
function searchInArray(arr, filtered, keys, include, regex) { | ||
for (const item of arr) { | ||
if (typeof item === 'string' && matchesRegex(item, regex)) { | ||
addIfUnique(filtered, item); | ||
function recursiveSearch(items, keys, include, regex, results) { | ||
if (Array.isArray(items)) { | ||
for (const item of items) { | ||
recursiveSearch(item, keys, include, regex, results); | ||
} | ||
else if (Array.isArray(item)) { | ||
searchInArray(item, filtered, keys, include, regex); | ||
} | ||
else if (typeof item === 'object' && item !== null) { | ||
searchInObject(item, filtered, keys, include, regex); | ||
} | ||
} | ||
else if (typeof items === 'object' && items !== null) { | ||
searchWithinObject(items, keys, include, regex, results); | ||
} | ||
else if (regex.test(String(items))) { | ||
addUniqueMatch(results, [items]); | ||
} | ||
} | ||
/** | ||
* Performs a search on an array of items or nested arrays/objects and returns the matched items. | ||
* Searches for items within a collection that match the given search text. | ||
* | ||
* @param {Partial<SearchOptions<T>>} options - An object containing search parameters. | ||
* @param {string} options.searchText - The text to search for. | ||
* @param {Array<SearchItem<T>>} options.searchItems - The items to search through. | ||
* @param {string[]} options.keys - Specific keys to include or exclude in the search. | ||
* @param {boolean} options.include - Flag to determine if the keys should be included or excluded. | ||
* @param {boolean} options.exact - Flag to determine if the search should be for an exact match. | ||
* @returns {Array<SearchItem<T>>} A filtered array of items that match the search criteria. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {Partial<SearchOptions>} options - The search parameters including searchText, searchItems, keys to search in, | ||
* whether to include keys and if the search is exact. | ||
* @returns {SearchItem[]} The matched items as an array. | ||
* | ||
* @example | ||
* // Assuming a predefined SearchItem type | ||
* const items = [{ name: 'John Doe' }, { name: 'Jane Doe' }]; | ||
* const results = search({ | ||
* searchText: 'Jane', | ||
* searchItems: items, | ||
* keys: ['name'], | ||
* // Define a list of objects to search | ||
* const people = [ | ||
* { name: "John", lastName: "Doe" }, | ||
* { name: "Jane", lastName: "Smith" }, | ||
* ]; | ||
* | ||
* // Options for searching | ||
* const options = { | ||
* searchText: "doe", | ||
* searchItems: people, | ||
* keys: ['lastName'], | ||
* include: true, | ||
* exact: false | ||
* }); | ||
* // results will be [{ name: 'Jane Doe' }] | ||
* }; | ||
* | ||
* // Perform the search | ||
* const found = search(options); | ||
* | ||
* // found will contain the object with lastName 'Doe' | ||
* console.log(found); // [{ name: "John", lastName: "Doe" }] | ||
*/ | ||
function search({ searchText = '', searchItems = [], keys = [], include = true, exact = false }) { | ||
const regex = exact | ||
? new RegExp(`^${searchText}$`, 'i') | ||
: new RegExp(searchText, 'i'); | ||
const filtered = []; | ||
searchItems.forEach((item) => { | ||
if (typeof item === 'string') { | ||
if (matchesRegex(item, regex)) { | ||
addIfUnique(filtered, item); | ||
} | ||
} | ||
else if (Array.isArray(item)) { | ||
searchInArray(item, filtered, keys, include, regex); | ||
} | ||
else if (typeof item === 'object' && item !== null) { | ||
searchInObject(item, filtered, keys, include, regex); | ||
} | ||
}); | ||
return filtered; | ||
const regex = new RegExp(exact ? `^${searchText}$` : searchText, 'i'); | ||
const results = []; | ||
const preparedItems = Array.isArray(searchItems) | ||
? searchItems | ||
: [searchItems]; | ||
const preparedKeys = keys.length > 0 ? keys : Object.keys(preparedItems[0] || {}); | ||
recursiveSearch(preparedItems, preparedKeys, include, regex, results); | ||
return results; | ||
} | ||
@@ -166,0 +144,0 @@ |
import { SearchItem } from './types'; | ||
/** | ||
* Searches through the properties of an object and adds matches to a filtered list. | ||
* If a property value is an array, it will recursively search through the array as well. | ||
* Searches for matches within an object based on a regex pattern. | ||
* If a match is found within the specified keys, it adds the object to the results. | ||
* | ||
* @param {SearchItem<T>} obj - The object to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within. | ||
* @param {SearchItem} object - The object to search within. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the property values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against the object values. | ||
* @param {SearchItem[]} results - The array to store matching objects. | ||
* | ||
* @example | ||
* const obj = { name: 'John', age: 30 }; | ||
* const filtered = []; | ||
* searchInObject(obj, filtered, ['name'], true, /John/); | ||
* // filtered now contains [{ name: 'John', age: 30 }] | ||
* // Define an object to search | ||
* const person = { name: "John", lastName: "Doe" }; | ||
* const results = []; | ||
* | ||
* // Search within the object for the name 'John' | ||
* searchWithinObject(person, ['name'], true, /John/i, results); | ||
* | ||
* // results will contain the person object | ||
* console.log(results); // [{ name: "John", lastName: "Doe" }] | ||
*/ | ||
export declare function searchInObject(obj: SearchItem, filtered: SearchItem[], keys: string[], include: boolean, regex: RegExp): void; | ||
export declare function searchWithinObject(object: SearchItem, keys: string[], include: boolean, regex: RegExp, results: SearchItem[]): void; | ||
/** | ||
* Searches through an array of items, adding matches to a filtered list. | ||
* If an item is an array itself, it will recursively search through that array as well. | ||
* Recursively searches through items for matches based on a regex pattern. | ||
* It handles both arrays and individual objects. | ||
* | ||
* @param {Array<SearchItem<T>>} arr - The array to search through. | ||
* @param {SearchItem<T>[]} filtered - The list to add matched items to. | ||
* @param {string[]} keys - The keys to search within if the items are objects. | ||
* @param {SearchItem | SearchItem[]} items - The items to search through. Can be a single item or an array of items. | ||
* @param {string[]} keys - The keys to include or exclude in the search. | ||
* @param {boolean} include - Whether to include or exclude the specified keys in the search. | ||
* @param {RegExp} regex - The regular expression to match against the item values. | ||
* @template T - The generic type parameter for the items being searched. | ||
* @param {RegExp} regex - The regex pattern to match against item values. | ||
* @param {SearchItem[]} results - The array to store matching items. | ||
* | ||
* @example | ||
* const items = [{ name: 'John' }, { name: 'Jane' }]; | ||
* const filtered = []; | ||
* searchInArray(items, filtered, ['name'], true, /Jane/); | ||
* // filtered now contains [{ name: 'Jane' }] | ||
* // Define a list of objects to search | ||
* const people = [ | ||
* { name: "John", lastName: "Doe" }, | ||
* { name: "Jane", lastName: "Doe" }, | ||
* ]; | ||
* const searchResults = []; | ||
* | ||
* // Recursively search for the term 'doe' in the list of people | ||
* recursiveSearch(people, ['lastName'], true, /doe/i, searchResults); | ||
* | ||
* // searchResults will contain both person objects | ||
* console.log(searchResults); // [{ name: "John", lastName: "Doe" }, { name: "Jane", lastName: "Doe" }] | ||
*/ | ||
export declare function searchInArray(arr: SearchItem[], filtered: SearchItem[], keys: string[], include: boolean, regex: RegExp): void; | ||
export declare function recursiveSearch(items: SearchItem | SearchItem[], keys: string[], include: boolean, regex: RegExp, results: SearchItem[]): void; |
@@ -1,1 +0,30 @@ | ||
export type SearchItem = Record<string, unknown>; | ||
/** | ||
* Represents a searchable item as a key-value record. | ||
* Any value type is allowed since the search functionality will cast to string for comparison. | ||
* | ||
* @example | ||
* // A sample SearchItem could look like this: | ||
* const item: SearchItem = { name: "John", age: 30, address: "123 Main St" }; | ||
*/ | ||
export type SearchItem = Record<string, any>; | ||
/** | ||
* Describes the options for the search function including the text to search for, the items to search within, | ||
* the keys in the items to consider, whether to include or exclude the specified keys, and whether the search should match exactly. | ||
* | ||
* @example | ||
* // An example of SearchOptions usage: | ||
* const options: SearchOptions = { | ||
* searchText: 'John', | ||
* searchItems: [{ name: 'John Doe', age: 28 }, { name: 'Jane Doe', age: 32 }], | ||
* keys: ['name'], | ||
* include: true, | ||
* exact: false | ||
* }; | ||
*/ | ||
export interface SearchOptions { | ||
searchText: string; | ||
searchItems: SearchItem | SearchItem[]; | ||
keys: string[]; | ||
include: boolean; | ||
exact: boolean; | ||
} |
import { SearchItem } from './types'; | ||
/** | ||
* Checks if a given value matches a regular expression. | ||
* Determines whether a given key is included in the search based on the include parameter and the keys provided. | ||
* | ||
* @param {unknown} value - The value to test against the regular expression. | ||
* @param {RegExp} regex - The regular expression to match. | ||
* @returns {boolean} True if the value is a string and matches the regex, false otherwise. | ||
* @param {string} key - The key to check. | ||
* @param {string[]} keys - The list of keys to consider in the search. | ||
* @param {boolean} include - Flag determining if the keys should be included or excluded from the search. | ||
* @returns {boolean} - True if the key is included in the search, false otherwise. | ||
* | ||
* @example | ||
* // returns true | ||
* matchesRegex('hello', /hello/); | ||
* | ||
* @example | ||
* // returns false | ||
* matchesRegex(123, /hello/); | ||
* // Check if 'name' is included in a search considering only 'name' and 'age': | ||
* console.log(isKeyIncluded('name', ['name', 'age'], true)); // Output: true | ||
* console.log(isKeyIncluded('address', ['name', 'age'], true)); // Output: false | ||
*/ | ||
export declare function matchesRegex(value: unknown, regex: RegExp): boolean; | ||
export declare function isKeyIncluded(key: string, keys: string[], include: boolean): boolean; | ||
/** | ||
* Determines whether a key should be included in the search based on the include parameter. | ||
* Adds a search item to the results if it's not already included. | ||
* | ||
* @param {string[]} keys - An array of keys to include or exclude. | ||
* @param {string} key - The current key to check. | ||
* @param {boolean} include - Whether to include or exclude the keys array. | ||
* @returns {boolean} True if the key should be included, false otherwise. | ||
* @param {SearchItem[]} results - The current list of search results. | ||
* @param {SearchItem} item - The item to potentially add to the results. | ||
* | ||
* @example | ||
* // returns true | ||
* shouldIncludeKey(['name', 'age'], 'name', true); | ||
* | ||
* @example | ||
* // returns false | ||
* shouldIncludeKey(['name', 'age'], 'location', true); | ||
* // Example usage of addUniqueMatch | ||
* const results: SearchItem[] = []; | ||
* const itemToAdd: SearchItem = { name: 'John', age: 30 }; | ||
* addUniqueMatch(results, itemToAdd); | ||
* console.log(results); // Output: [{ name: 'John', age: 30 }] | ||
*/ | ||
export declare function shouldIncludeKey(key: string, keys: string[], include: boolean): boolean; | ||
/** | ||
* Adds an item to the filtered list if it is not already present. | ||
* | ||
* @param {SearchItem<T>[]} filtered - The array to which the item will be added if it is unique. | ||
* @param {SearchItem<T>} item - The item to add if it is not already present in the array. | ||
* | ||
* @example | ||
* // filtered contains [{name: 'John'}, {name: 'Jane'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'Jane'}); | ||
* | ||
* @example | ||
* // filtered remains unchanged [{name: 'John'}] | ||
* const filtered = [{name: 'John'}]; | ||
* addIfUnique(filtered, {name: 'John'}); | ||
*/ | ||
export declare function addIfUnique(filtered: SearchItem[], item: SearchItem): void; | ||
export declare function addUniqueMatch(results: SearchItem[], item: SearchItem): void; |
@@ -53,3 +53,3 @@ { | ||
"types": "lib", | ||
"version": "2.0.0-beta.1" | ||
"version": "2.0.0-beta.2" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100862
29
1128
1