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 🙏

© 2024 – Pkg Stats / Ryan Hefner

handy-filter

v1.2.0

Published

Handy Filter is a JavaScript library for handy arrays filtration. With her you can filter by conditions of any complexity in declarative style

Downloads

46

Readme

Handy Filter GitHub license npm version

Overview

Handy Filter is a JavaScript/TypeScript library for handy arrays filtration. With her you can filter by conditions of any complexity in declarative style.

If you want to work with React see handy-filter-hook

Installation

npm:

npm install handy-filter

yarn:

yarn add handy-filter

Table of Contents

Usage

Base usage

import Filter, { gte, lt, not, eq } from 'handy-filter';

// num < 10 or num >= 100 and num !== 500
const filter = new Filter(lt(10)).or(gte(100)).and(not(eq(500)));
const example = [2, 1, 3, 10, 5, 10, 100, 1000, 200, 10, 500];

filter.filter(example); // result is [2, 1, 3, 5, 100, 1000, 200]

See more about Conditions.

NOTE that you can pass to the methods any number of conditions.

With an array of objects

You can use the Filter with an array of objects.

You can filter objects by properties of any deep.

import Filter, { eq, gt, not } from 'handy-filter';

const example = [
  { num: 20, nested: { str: 'bar', prop: true }},
  { num: 100, nested: { str: 'bar', prop: false }},
  { num: 100, nested: { str: 'foo', prop: null }},
  { num: 10, nested: { str: 'bar', prop: true }},
];

// obj.num > 20 and obj.nested.prop !== null or obj.nested.str === 'foo'
const filter = new Filter(gt('num', 20)).and(not(eq('nested.prop', null))).or(eq('nested.str', 'foo'));

filter.filter(example);
// result is [
//   { num: 100, nested: { str: 'bar', prop: false }},
//   { num: 100, nested: { str: 'foo', prop: null }},
// ]

Plain syntax

It is just another way to use conditions.

import Filter from 'handy-filter';

const example = [
  { num: 20, nested: { str: 'bar', prop: true }},
  { num: 100, nested: { str: 'bar', prop: false }},
  { num: 100, nested: { str: 'foo', prop: null }},
  { num: 10, nested: { str: 'bar', prop: true }},
];

// obj.num > 20 and obj.nested.prop !== null or obj.nested.str === 'foo'
const filter = new Filter(['num__gt', 20]).and(['nested.prop__eq', false]).or(['nested.str__eq', 'foo']);

filter.filter(example);
// result is [
//   { num: 100, nested: { str: 'bar', prop: false }},
//   { num: 100, nested: { str: 'foo', prop: null }},
// ]

See more about Conditions.

Create filter in runtime

import Filter, { lt, lte, gt, eq } from 'handy-filter';

let filter1 = new Filter(lte((20)));

if (Math.random() < 0.5) {
  filter = filter.and(gt(10));
} else {
  filter = filter.and(lt(30)).or(eq(100));
}

NOTE that "and" and "or" methods create a new instance of the Filter:

import Filter, { lte, gt } from 'handy-filter';

const filter1 = new Filter(lte(20));
// the filter1 still contain the "lte(20)" condition, but filter2 contain "lte(20) and gt(10)"
const filter2 = filter1.and(gt(10));

The __any__ value

To make a condition always true, you can use the __any__. This can be useful if you don't want to change a structure of the filter, but want to change his values. Or, for example, you want to disable a part of the filter condition.

import Filter, { ANY, not, eq, lt, gt, gte } from 'handy-filter';

// This is equivalent to "value !== 20 and value < 100"
new Filter(not(eq(20))).and(gt('__any__')).and(lt(100)).and(not(eq(ANY)));

// This will always be true
new Filter(not(eq(20))).or(lt(100)).or(gte('__any__'));

The Filter automatically optimising conditions containing __any__ values, so you don't need to worry about performance.

Conditions

Simple conditions

Simple conditions work with all basic types.

| Name | Alias | Purpose | |:--------------------|:-----:|:-------------------------------------------------------:| | Equal | eq | Check if a value is equal to another value | | Greater | gt | Check if a value is greater than another value | |Greater than or equal| gte |Check if a value is grater than or equal to another value| | Less | lt | Check if a value less than another value | | Less than or equal | lte | Check if a value less than or equal to another value |

Logical conditions

Can check values of any base type, but only conditions can be passed as constructor parameters:

| Name | Alias | Purpose | |:--------------------|:-----:|:-------------------------------------------------------:| | And | and | Combine other conditions through logical "and" | | Or | or | Combine other conditions through logical "or" | | Not | not | Takes truth to falsity and vice versa |

Range conditions

These conditions check if a value is in some range/set. Work with all base types.

| Name | Alias | Purpose | |:--------------------|:-----:|:-------------------------------------------------------:| | In | inl | Check if a value is in a list of values |

RegExp conditions

Can check values of any base type, but only values of type string or RegExp can be passed as constructor parameters.

NOTE that RegExp conditions automatically convert all values to string type.

| Name | Alias | Purpose | |:--------------------|:-----:|:-------------------------------------------------------:| | Contain | cnt | Check if a value contains another value | | Ignore case contain | icnt | Check if a value contains another value |

Independent use

You can use conditions independently of the filter:

import { and, or, eq } from 'handy-filter';

const user = {
  active: true,
  isAdmin: false,
  permissions: {
    canWrite: true,
    canRead: true,
  },
};

const isActive = eq('active', true);
const isAdmin = eq('isAdmin', true);
const canWrite = and(isActive, or(isAdmin, eq('permissions.canWrite', true)));

if (canWrite.check(user)) {
// do somthing
}

Supported types

  1. bigint;
  2. boolean;
  3. Date;
  4. null;
  5. number;
  6. string;
  7. undefined.

Filter options

The Filter constructor can receive options object as the second parameter.

addTo

| Valid values | Default | |:--------------|:-------:| | all, latest | latest |

This option changes how the filter add new conditions using "and" and "or" methods:

import Filter, { and, not, or, eq, gt, lte } from 'handy-filter';

const values = [4, 1, 60, 3, 5, 10, 50, 20, 100, 30, 1000];

// This is equivalent to "value < 0 or value > 50 and value <= 100 or value != 60 and value === 30"
const defaultFilter = new Filter(lt(0)).or(gt(50)).and(lte(100)).or(not(eq(60))).and(eq(30));
// This is equivalent to "(((value < 0 or value > 50) and value <= 100) or value != 60) and value === 30"
const filterWithOption = new Filter(lt(0), { addTo: 'all' }).or(gt(50)).and(lte(100)).or(not(eq(60))).and(eq(30));

defaultFilter.filter(values); // result is [60, 100, 30]
filterWithOption.filter(values); // result is [30]