npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@storm-g/multi-filter

v0.1.7

Published

A lightweight and simple TypeScript package to help filter arrays. Provides intelityping for filtering to help with code completions and prevent errors. Increases the readability of code when using multiple filters.

Readme

README

multi-filter

A lightweight and simple package for making complex array filtering easier to read and write. It is often necessary to apply multiple checks or functions when filtering arrays. This is often approached by either creating large and convoluted functions, or by chaining multiple arr.filter calls one after another. These approaches are often frustrating to implement, read, and maintain. This package aims to make the process easier, while also providing powerful typing and type-hinting.

Version: 0.1.7

View the source code on Bitbucket

Install

npm add @storm-g/multi-filter

Usage

Most of the time you would only be making use of the createFilterFunc and combineFilters functions (or their aliases).

import { createFilterFunc, combineFilters } from '@storm-g/multi-filter';

Though you may want to make use of the provided types such as Operator and FilterFunc<T>.

import { FilterFunc } from '@storm-g/multi-filter/types/filtering';
import { Operator } from '@storm-g/multi-filter/types/operators';
/* etc. */

Example

Say we need to filter an array arr by a number of conditions.

  1. for element e of arr 20 <= e.age < 30
  2. for e of arr e.city.name must be in Rome, London, Cape Town
  3. for e of arr e.surname != Smith ...

Usually this problem would be solved by implementing one complex filter function which performs all checks, or by chaining multiple filter calls together. one messy function

const f = (e: T): boolean => {
    if (e.age < 20 || e.age >= 30) {
        return false;
    }
    if (!['Rome', 'London', 'Cape Town'].includes(e.city.name)) {
        return false;
    }
    if (e.surname == 'Smith') {
        return false;
    }
    /* ... */
    return true;
}
arr = arr.filter(f);

chained filters

    arr = arr
        .filter((e: T): boolean => e.age >= 20 && e.age < 30)
        .filter((e: T): boolean => ['Rome', 'London', 'Cape Town'].includes(e.city.name))
        .filter((e: T): boolean => e.surname != 'Smith')
        .filter(/* ... */);

Instead, we can use multi-filter to neatly and intuitively write these filters as

import {combineFilters, createFilterFunc} from '@storm-g/multi-filter';

const f = combineFilters([
    createFilterFunc('age', '>=', 20),
    createFilterFunc('age', '<', 30),
    createFilterFunc((e: T) => e.city.name, 'in', ['Rome', 'London', 'Cape Town']),
    createFilterFunc('surname', '!=', 'Smith'),
    /* ... */
]);
arr = arr.filter(f);

AND/OR filtering

multi-filter has an additional advantage. Filters can be combined with an OR relation, meaning that an element is included in the filtered result as soon as the first filter function returns a truthy value. If we took the above example and changed it from requiring all conditions to be true to just requiring one (OR) filtering becomes even more tedious. Essentially this example would require something like:

const f = (e: T): boolean => {
    if (e.age >= 20 && e.age < 30) {
        return true;
    }
    if (['Rome', 'London', 'Cape Town'].includes(e.city.name)) {
        return true;
    }
    if (e.surname != 'Smith') {
        return true;
    }
    /* ... */
    return false;
}

Using multi-filter is easier to read and write, essentially being identical as before but with the addition of one parameter:

import {combineFilters, createFilterFunc} from '@storm-g/multi-filter';

const f = combineFilters(
    [
        createFilterFunc('age', '>=', 20),
        createFilterFunc('age', '<', 30),
        createFilterFunc((e: T) => e.city.name, 'in', ['Rome', 'London', 'Cape Town']),
        createFilterFunc('surname', '!=', 'Smith'),
        /* ... */
    ],
    'OR'
);
arr = arr.filter(f);

Furthermore, this allows for the creation of complex filters by nesting combineFilters calls:

// Filter array, arr, where fa(x) or fb(x) is true, and fc(x) or fd(x) are true.
const f = combineFilters(
    [
        combineFilters([fa, fb], 'OR'),
        combineFilters([fc, fd], 'OR'),
    ], 'AND'
);
arr = arr.filter(f);

We don't have to make use 'AND' | 'OR' exclusively. The project makes use of helpful types and even an AndOr enum. This means the string value is not case-sensitive and in the case of 'AND' we could also use &&, AndOr.AND, AND (if the const is imported).

import { AndOr, OR } from '@storm-g/multi-filter/types/operators';
/* all following cases are equivalent */
combineFilters([fa, fb], '||');
combineFilters([fa, fb], 'or');
combineFilters([fa, fb], 'Or');
combineFilters([fa, fb], 'Or');
combineFilters([fa, fb], AndOr.OR);
combineFilters([fa, fb], OR);

Externally, you can make use of the versatility

import {isAnd, isOr, toAndOr} from '@storm-g/multi-filter/types/operators';
isOr('oR'); // returns true
isAnd('&&'); // returns true
toAndOr('aND'); // returns 'AndOr.AND'

If you prefer, we can even use dedicated functions and, or which call combineFilters with the appropriate parameter. This could further increase readability.

import {and, or} from '@storm-g/multi-filter';
// Filter array, arr, where fa(x) or fb(x) is true, and fc(x) or fd(x) are true.
const f = and(
    or(fa, fb),
    or(fc, fd),
);
arr = arr.filter(f);

Performance note: combineFilters prioritizes readability and type-hiting etc. For small arrays, chained arr.filtercalls are often faster. For larger arrays, avoiding multiple passes over the data, combineFilter is often more efficient.

Take a look at the included benchmarks. Enhancements to efficiency on smaller arrays is planned and intended to at least match chained calls.

Aliases

If the function names are a little verbose for your liking, there are shorter aliases available:

| function | alias | |--------------------|--------------------| | combineFilters | combine, com | | createFilterFunc | filterFunc, ff |