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

query-methods

v1.0.5

Published

SQL-like query methods for arrays in JavaScript

Downloads

11

Readme

Query methods

CircleCI

This library provides JavaScript methods to perform query operations like selecting, filtering, grouping and ordering on arrays of objects.

The Query class receives an array in its constructor and has several methods that can be used to build the desired result.

import { Query } from 'query-methods';

const elements = [
  { id: 1, key: 'a', value: 10 },
  { id: 2, key: 'b', value: 20 },
  { id: 3, key: 'c', value: 30 }
];

const query = new Query(elements);

query.select('id').where({ value: v => v > 15}).all;
// [{ id: 2 }, { id: 3 }]

Install

Query methods is available as a package in npm:

npm install query-methods

Methods

Getters

The Query class has the following getters:

  • all: returns every result of the query;
  • first: returns the first result of the query;
  • last: returns the last result of the query;

Example:

const query = new Query([1, 2, 3]);

query.all;   // [1, 2, 3]
query.first; // 1
query.last;  // 3

Methods

The Query class has the following methods:

  • select: the values used to select attributes;
  • where: the conditions used to filter the results;
  • group: the attributes used to group the results;
  • order: the methods used to order the results;
  • limit: limits the result of the query;
  • offset: offsets the result of the query;

Select

It accepts strings, objects and functions as arguments:

  • String: the name of the attribute to select;
  • Object:
    • key: the name of the attribute in the result;
    • value:
      • String: the name of the attribute to select;
      • Function: receives the element and returns the value to select;
  • Function: receives the element and returns the value to select. The name of the function is used as the name of the attribute in the result.
const query = new Query([{ id: 1, key: 'a', price: 10 }]);

const result = query.select(
  'key',
  {
    fullPrice: 'price',
    discountedPrice: e => e.price * 0.9;
  }
  function custom(e) { return `${e.id}-${e.key}` }
).all;
// [{ key: 'a', fullPrice: 10, discountedPrice: 9, custom: '1-a' }]

Where

It accepts functions and objects as arguments:

  • Function: receives the element and returns a Boolean indicating if it should be selected;
  • Object:
    • key: the name of the attribute to check;
    • value:
      • Function: receives the element's attribute and returns a Boolean;
      • other value: checks if the attribute equals the value.
const query = new Query(elements);

const result = query.where(
  element => element.price < 100, // elements with price < 100
  {
    key: 'a',                     // elements with key === 'a'
    price: price => price > 10    // elements with price > 10
  }
).all;

The library provides some functions that help building queries with where statements:

  • eq: Checks if an attribute is equal to a value;
  • not: Checks if an attribute is not equal to a value;
  • lt: Checks if an attribute is less than a value;
  • lte: Checks if an attribute is less than or equal to a value;
  • gt: Checks if an attribute is greater than a value;
  • gte: Checks if an attribute is greater than or equal to a value;
const result = query.where({
  key: not('a'), // key !=== 'a'
  price: lt(100) // price < 100
}).all;

Group

It accepts the same arguments as the select methods:

  • String: the name of the attribute to group by;
  • Object:
    • key: the name of the attribute in the result;
    • value:
      • String: the name of the attribute to group;
      • Function: receives the element and returns the value to group;
  • Function: receives the element and returns the value to group. The name of the function is used as the name of the attribute in the result.

The grouped values are returned in the result by default.

const elements = [{ key: 'A' }, { key: 'a' }];
let query, result;

query = new Query(elements);
result = query.group('key').all;
// [{ key: 'A' }, { key: 'a' }]

query = new Query(elements);
result = query.group({ uppercaseKey: e => e.key.toUpperCase() }).all;
// [{ uppercaseKey: 'A' }]

Order

It accepts functions and objects as arguments:

  • Function: receives two elements and should return a negative number, zero or a positive number indicating the order of the elements, similar to the native Array#sort method;
  • Object:
    • key: the name of the attribute used to order;
    • value: a Function that receives two attributes and should return the number indicating their order.
const query = new Query(elements);

const result = query.order({
  key: (a, b) => a.localeCompare(b),
  price: (a, b) => a - b
}).all;

The library provides some functions to help building queries with order:

  • asc.number: orders numbers in an ascending order;
  • asc.string: orders strings in an ascending order;
  • desc.number: orders numbers in an descending order;
  • desc.string: orders strings in an descending order;
const result = query.order({
  key: asc.string,
  price: desc.number
}).all;

Limit and offset

Each method accepts a single integer as argument:

  • limit: limits the quantity of elements in the result;
  • offset: skips the first elements of the result.
const query = new Query([1, 2, 3, 4]);

const result = query.limit(2).offset(1).all;
// [2, 3]

Aggregate functions

When the query receives group arguments, the behavior of the select method changes, allowing it to use aggregate functions:

const query = new Query([
  { price: 10 },
  { price: 20 }
]);

const result = query.group('key').select({
  maxPrice: elements => {
    const prices = elements.map(e => e.price);
    return Math.max(...prices);
  }
}).all;

The library provides some aggregate functions to make group queries easier:

  • min: accepts the name of the attribute to calculate the minimum;
  • max: accepts the name of the attribute to calculate the maximum;
  • sum: accepts the name of the attribute to calculate the total;
  • average: accepts the name of the attribute to calculate the average;
  • count: counts the number of elements in the group;
const query = new Query([
  { key: 'a', price: 10 },
  { key: 'a', price: 20 },
  { key: 'b', price: 30 },
  { key: 'b', price: 40 }
]);

const result = query.group('key').select({
  maxPrice: max('price'),
  minPrice: min('price'),
  averagePrice: average('price'),
  sumPrice: sum('price'),
  count: count()
}).all;

// [{ key: 'a', maxPrice: 20, minPrice: 10, ... }, { key: 'b', ... }]