super-utils-plus
Version:
A superior alternative to Lodash with improved performance, TypeScript support, and developer experience
108 lines (107 loc) • 3.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.filter = filter;
exports.reject = reject;
const is_1 = require("../utils/is");
/**
* Iterates over elements of collection, returning an array of all elements
* the predicate returns truthy for.
*
* @param collection - The collection to iterate over
* @param predicate - The function invoked per iteration
* @returns The new filtered array
*
* @example
* ```ts
* const users = [
* { 'user': 'barney', 'age': 36, 'active': true },
* { 'user': 'fred', 'age': 40, 'active': false }
* ];
*
* filter(users, function(o) { return !o.active; });
* // => objects for ['fred']
*
* // The `_.matches` iteratee shorthand.
* filter(users, { 'age': 36, 'active': true });
* // => objects for ['barney']
*
* // The `_.matchesProperty` iteratee shorthand.
* filter(users, ['active', false]);
* // => objects for ['fred']
*
* // The `_.property` iteratee shorthand.
* filter(users, 'active');
* // => objects for ['barney']
* ```
*/
function filter(collection, predicate) {
if (!collection || !collection.length) {
return [];
}
// Convert predicate to a function if it's not already one
let predicateFn;
if (typeof predicate === 'function') {
// Function predicate
predicateFn = predicate;
}
else if ((0, is_1.isArray)(predicate) && predicate.length === 2) {
// Property and value pair
const [prop, value] = predicate;
predicateFn = (item) => {
return (0, is_1.isObject)(item) && item[prop] === value;
};
}
else if ((0, is_1.isObject)(predicate)) {
// Object matching
predicateFn = (item) => {
if (!(0, is_1.isObject)(item))
return false;
const objItem = item;
const objPred = predicate;
for (const key in objPred) {
if (objItem[key] !== objPred[key]) {
return false;
}
}
return true;
};
}
else if (typeof predicate === 'string') {
// Property name
const prop = predicate;
predicateFn = (item) => {
return (0, is_1.isObject)(item) && Boolean(item[prop]);
};
}
else {
// Default to identity function
predicateFn = Boolean;
}
return collection.filter(predicateFn);
}
/**
* The opposite of filter; this method returns the elements of collection
* that predicate does NOT return truthy for.
*
* @param collection - The collection to iterate over
* @param predicate - The function invoked per iteration
* @returns The new filtered array
*
* @example
* ```ts
* const users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true }
* ];
*
* reject(users, function(o) { return !o.active; });
* // => objects for ['fred']
* ```
*/
function reject(collection, predicate) {
// Reuse filter but negate the predicate
const filterPredicate = typeof predicate === 'function'
? (value, index, collection) => !predicate(value, index, collection)
: (value) => !filter([value], predicate).length;
return filter(collection, filterPredicate);
}