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

butterfly-data-filters

v0.8.0

Published

A simple library for filtering data in JavaScript

Downloads

135

Readme

butterflyDataFilters

A simple library for data filtering in JavaScript.

.github/workflows/test.yml Coverage Status

Motivation

We needed a simple, yet expandable way to filter locally cached data in a single page application.
Because we did not find anything that was simple enough while also meeting all of our needs, we wrote a quick script to do so.

Since this script is not too specific for the application it was written for, we decided to share it with the open source community in hopes that someone else may benefit from it as well.

How does it work?

For direct examples, check out src/tests/filterHelper.test.js since it shows all ways the filters can be used.

  • Install the library using npm save --dev butterfly-data-filters
  • Add import {applyFilters} from 'butterfly-data-filters'; where you want to use the filters
    • You can also import availableFilterTypes, which is a list of all types supported.
      • This list may be useful for validation before calling the filters or within React PropTypes
  • Build your filters like in the examples below and combine them into a single array
  • Call applyFilters(filters, values, skipUndefined)
    • If skipUndefined is false, only datasets that contain all fields that your filter apply to will be returned

Substring filters

In order to filter your dataset for values that contain a certain substring, you will have to format your filters like so:

{
    'field': 'searchField',
    'type': 'string',
    'value': 'substring',
},

Array filters

In order to filter your dataset for a list of values, you can use array filters:

{
  'field': 'searchField',
  'type': 'array',
  'value': ['honk', 'goose'],
},

This filter will return all datasets where searchField is either honk or goose.
You can also pass ['_any'] or just the string _any as value to get all datasets and effectively skip this filter.
This is useful as a default value when you don't know what the possible filter options are in advance.

Array includes filters

In order to filter your dataset for fields where an array field contains a certain value, you can use arrayIncludes filters:

{
    field: 'searchField',
    type: 'arrayIncludes',
    value: 'banana',
}

This filter will return all datasets where searchField is an array that includes the string banana.

Array includes array filters

Similarly, you can search for fields where an array field contains any of a given list of values using arrayIncludesArray filters:

{
    field: 'test',
    type: 'arrayIncludesArray',
    value: ['banana', 'apple'],
}

This will return all datasets where searchField is an array that includes either banana or apple (or both).

Strict array includes array filters

If you only want fields where an array field contains all of a given list of values, you can use arrayIncludesArrayStrict filters:

{
    field: 'test',
    type: 'arrayIncludesArrayStrict',
    value: ['apple', 'banana'],
}

This will only return datasets where searchField is an array that contains both apple and banana.

Date filters

There are a number of filters that allow you to search for datasets with specific date values.
In general, these can be called with either a properly formatted string (a string that new Date() understands) or a vanillaJS Data object as value.

minDate

This filter will return any datasets where the search field date is after the specified one.

{
  'field': 'searchField',
  'type': 'minDate',
  'value': '2021-01-01',
}

maxDate

This filter will return any datasets where the search field date is before the specified one.

{
  'field': 'searchField',
  'type': 'maxDate',
  'value': '2021-01-01',
}

dateRange

This filter lets you specify different date ranges to search for.
You may use one of the following date range presets:

  • today
  • yesterday
  • 7days (the last week)
  • month (the current month)
  • last_month

Or a custom range like this:

{
  'field': 'searchField',
  'type': 'dateRange',
  'value': 'custom',
  'data': {
      'from': '2020-01-01',
      'until': '2020-02-01',
  },
},

You can also skip dateRange checks by setting the value to _any.

dateTimeRange

This filter lets you specify different date-time ranges to search for.

{
  'field': 'searchField',
  'type': 'dateTimeRange',
  'data': {
      'from': '2020-01-01T01:00',
      'until': '2020-02-01T23:00',
  },
},

You can also skip dateTimeRange checks by setting the value to _any.

Minimum number filters

You can filter for numeric numbers that are higher than a specified one like this:

{
  'field': 'searchField',
  'type': 'minNum',
  'value': 1,
},

Maximum number filters

You can filter for numeric numbers that are lower than a specified one like this:

{
  'field': 'searchField',
  'type': 'maxNum',
  'value': 10,
},

Strict equality filters

Use this filter to search for strict equality:

{
  'field': 'searchField',
  'type': 'strict',
  'value': false,
},

Lax equality filters

Use this filter to search for lax equality:

{
  'field': 'searchField',
  'type': 'strict',
  'value': 123,
},

Note that you should not use this if it can be helped because it will lead to potentially unexpected results due to type coercion.

Lax truthiness filters

Use this filter to search for datasets that have a truthy value as searchField

{
  'field': 'bool',
  'type': 'laxTrue',
},

Lax falsiness filters

Use this filter to search for datasets that have a falsy value as searchField

{
  'field': 'bool',
  'type': 'laxFalse',
},

Existence check filters

Use this filter to search for datasets that have any value set (or no value at all) for searchField.
Note that this filter overrides the skipUnset param.

{
    'field': 'test',
    'type': 'existence',
    'value': true,
},

You can also pass the array [true, false] or [_any] to this filter to effectively skip it.
This is useful when using material-ui multi selects.

Emptiness check filter

Use this filter to search for datasets that have an empty value set for searchField. Note that this filter overrides the skipUnset param.

{
    'field': 'test',
    'type': 'emptiness',
    'value': [true, false]
}

You can pass either a boolean or an array that contains one or two booleans or the string _any.
Pass true to only get fields with an emtpy value and false for fields with non empty values.
In this regard, the filter works exactly opposite to the existence filter.

Note that this filter will not work as expected for object children as they are always considered non empty.

Child attribute filters

With the childAttr filter type, you can search child fields recursively like this:

{
  'field': 'child',
  'type': 'childAttr',
  'data': {
      child: {
          field: 'searchField',
          type: 'strict',
          value: 'foo',
      },
},

You can use any filter type (including childAttr and childArrayAttr) in your child filter.

Array child attribute filters

This filter functions just like the childAttr type but instead of querying a single child field. It can be used to go through an array of child objects and return all datasets where at least one child fits the filter.

{
    field: 'children',
    type: 'childArrayAttr',
    data: {
        child: {
            field: 'searchField',
            type: 'strict',
            value: 'foo',
        },
    },
},

Helper functions

convertDateRangeValueToBeComparable

This function is used internally to convert a DateRange filter to a from and until Date object with which values can be compared.
It is also exported by the library since it may be useful in some cases.

This function requires the filter value and data within an object as param.
It will either return an array with from and until values or true if the filter should always return true for the given value.

Known issues

Currently, idea IDEs refuse to autocomplete anything imported from this package and mark any usages as unresolvable.
If someone knows how to fix that, help would be very appreciated.

This library was build for a specific dataset, following yagni (you aren't gonna need it) principles to some extent.
While it is meant to be used across projects, there are definitely some useful things that have not yet been implemented.

This library is expected to grow over time and more features will be added.

Contributing

Contributions are very welcome, even if they are not related to code.
If you found any bugs or are missing some specific feature, please file an issue.

Pull requests are obviously also very welcome.
However, please note that we can only accept PRs that do not lower our test coverage of 100%.

In order to check that coverage, run npm run coverage before creating your pull request.