remeda
Version:
A utility library for JavaScript and Typescript.
1 lines • 4.99 kB
Source Map (JSON)
{"version":3,"file":"filter.cjs","names":["purry","SKIP_ITEM"],"sources":["../src/filter.ts"],"sourcesContent":["import type { Writable } from \"type-fest\";\nimport type { FilteredArray } from \"./internal/types/FilteredArray\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport type { LazyEvaluator } from \"./internal/types/LazyEvaluator\";\nimport { SKIP_ITEM } from \"./internal/utilityEvaluators\";\nimport { purry } from \"./purry\";\n\n// When the predicate used for filter isn't refining (like a type-predicate) we\n// can narrow the result slightly if it's also trivial (it returns the same\n// result for all items). This is uncommon, but can be useful to \"short-circuit\"\n// the filter.\ntype NonRefinedFilteredArray<\n T extends IterableContainer,\n IsItemIncluded extends boolean,\n> = boolean extends IsItemIncluded\n ? // We don't know which items of the array the predicate would allow in the\n // output so we can only safely say that the result is an array with items\n // from the input array.\n // TODO: Theoretically we could build an output shape that would take into account the **order** of elements in the input array by reconstructing it with every single element in it either included or not, but this type can grow to a union of as much as 2^n options which might not be usable in practice.\n Array<T[number]>\n : IsItemIncluded extends true\n ? // If the predicate is always true we return a shallow copy of the array.\n // If it was originally readonly we need to strip that away.\n Writable<T>\n : // If the predicate is always false we will always return an empty\n // array.\n [];\n\n/**\n * Creates a shallow copy of a portion of a given array, filtered down to just\n * the elements from the given array that pass the test implemented by the\n * provided function. Equivalent to `Array.prototype.filter`.\n *\n * @param data - The array to filter.\n * @param predicate - A function to execute for each element in the array. It\n * should return `true` to keep the element in the resulting array, and `false`\n * otherwise. A type-predicate can also be used to narrow the result.\n * @returns A shallow copy of the given array containing just the elements that\n * pass the test. If no elements pass the test, an empty array is returned.\n * @signature\n * R.filter(data, predicate)\n * @example\n * R.filter([1, 2, 3], x => x % 2 === 1) // => [1, 3]\n * @dataFirst\n * @lazy\n * @category Array\n */\nexport function filter<\n T extends IterableContainer,\n Condition extends T[number],\n>(\n data: T,\n predicate: (value: T[number], index: number, data: T) => value is Condition,\n): FilteredArray<T, Condition>;\nexport function filter<\n T extends IterableContainer,\n IsItemIncluded extends boolean,\n>(\n data: T,\n predicate: (value: T[number], index: number, data: T) => IsItemIncluded,\n): NonRefinedFilteredArray<T, IsItemIncluded>;\n\n/**\n * Creates a shallow copy of a portion of a given array, filtered down to just\n * the elements from the given array that pass the test implemented by the\n * provided function. Equivalent to `Array.prototype.filter`.\n *\n * @param predicate - A function to execute for each element in the array. It\n * should return `true` to keep the element in the resulting array, and `false`\n * otherwise.\n * @returns A shallow copy of the given array containing just the elements that\n * pass the test. If no elements pass the test, an empty array is returned.\n * @signature\n * R.filter(predicate)(data)\n * @example\n * R.pipe([1, 2, 3], R.filter(x => x % 2 === 1)) // => [1, 3]\n * @dataLast\n * @lazy\n * @category Array\n */\nexport function filter<\n T extends IterableContainer,\n Condition extends T[number],\n>(\n predicate: (value: T[number], index: number, data: T) => value is Condition,\n): (data: T) => FilteredArray<T, Condition>;\nexport function filter<\n T extends IterableContainer,\n IsItemIncluded extends boolean,\n>(\n predicate: (value: T[number], index: number, data: T) => IsItemIncluded,\n): (data: T) => NonRefinedFilteredArray<T, IsItemIncluded>;\n\nexport function filter(...args: ReadonlyArray<unknown>): unknown {\n return purry(filterImplementation, args, lazyImplementation);\n}\n\nconst filterImplementation = <T>(\n data: ReadonlyArray<T>,\n predicate: (value: T, index: number, array: ReadonlyArray<T>) => boolean,\n): Array<T> => data.filter(predicate);\n\nconst lazyImplementation =\n <T>(\n predicate: (value: T, index: number, data: ReadonlyArray<T>) => boolean,\n ): LazyEvaluator<T> =>\n (value, index, data) =>\n predicate(value, index, data)\n ? { done: false, hasNext: true, next: value }\n : SKIP_ITEM;\n"],"mappings":"sFA6FA,SAAgB,EAAO,GAAG,EAAuC,CAC/D,OAAOA,EAAAA,EAAM,EAAsB,EAAM,EAAmB,CAG9D,MAAM,GACJ,EACA,IACa,EAAK,OAAO,EAAU,CAE/B,EAEF,IAED,EAAO,EAAO,IACb,EAAU,EAAO,EAAO,EAAK,CACzB,CAAE,KAAM,GAAO,QAAS,GAAM,KAAM,EAAO,CAC3CC,EAAAA"}