json-fetchfy
Version:
A lightweight Node.js module to fetch, validate, and manipulate JSON data from various sources seamlessly.
64 lines (55 loc) • 2.29 kB
JavaScript
/**
* Searches for elements in an array based on a query.
* @module advancedFindInArray
*/
/**
* @typedef {Object} FindInArrayOptions
* @property {boolean} [deep=false] - If true, performs deep comparison for object queries.
* @property {boolean} [caseSensitive=true] - If false, performs case-insensitive string comparisons.
* @property {number} [limit] - Maximum number of results to return.
*/
/**
* Finds elements in an array based on a query.
* @param {Array} array - The array to search.
* @param {*} query - The query to match against array elements.
* @param {(string|string[])} [key=null] - The key(s) to search in objects. Can be a dot-notated string for nested properties or an array of keys.
* @param {FindInArrayOptions} [options] - Additional options for the search.
* @throws {TypeError} If the first argument is not an array.
* @returns {Array} An array of matching elements.
*/
function findInArray(array, query, key = null, options = {}) {
if (!Array.isArray(array)) {
throw new TypeError("The first argument must be an array");
}
const {
deep = false,
caseSensitive = true,
limit = Infinity
} = options;
const compareValues = (a, b) => {
if (!caseSensitive && typeof a === 'string' && typeof b === 'string') {
return a.toLowerCase() === b.toLowerCase();
}
if (deep && typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {
return JSON.stringify(a) === JSON.stringify(b);
}
return a === b;
};
const getNestedValue = (obj, path) => {
const keys = Array.isArray(path) ? path : path.split('.');
return keys.reduce((acc, key) => (acc && acc[key] !== undefined) ? acc[key] : undefined, obj);
};
let filteredArray;
if (typeof query === "function") {
filteredArray = array.filter(query);
} else if (key) {
filteredArray = array.filter(item => {
const value = getNestedValue(item, key);
return compareValues(value, query);
});
} else {
filteredArray = array.filter(item => compareValues(item, query));
}
return filteredArray.slice(0, limit);
}
export default findInArray;